TCMiranda / joi-extract-type

Provides native type extraction from Joi schemas for Typescript
MIT License
151 stars 27 forks source link

Feature/joi16 #28

Closed ChrisCrewdson closed 4 years ago

ChrisCrewdson commented 4 years ago

We are attempting to solve Issue 22 and I think we're close. There are a few changes including:

  1. Moving out of the Joi namespace to avoid collisions
  2. Terminating types with methods like __stringSchema to keep them distinct

This is the remaining error:

$ tsc
index.ts:302:20 - error TS2430: Interface 'AlternativesSchema<N>' incorrectly extends interface 'AnySchema<any>'.
  The types returned by 'when(...)' are incompatible between these types.
    Type 'this extends AlternativesSchema<infer O> ? O extends Box<infer oT, infer oR> ? AlternativesSchema<BoxType<O, any>> : AlternativesSchema<Box<any, false>> : AlternativesSchema<...>' is not assignable to type 'this'.
      Type 'AlternativesSchema<Box<any, false>>' is not assignable to type 'this'.
        Type 'N extends Box<infer oT, infer oR> ? AlternativesSchema<BoxType<N, any>> : AlternativesSchema<Box<any, false>>' is not assignable to type 'this'.
          Type 'AlternativesSchema<Box<any, false>> | AlternativesSchema<BoxType<N, any>>' is not assignable to type 'this'.
            Type 'AlternativesSchema<Box<any, false>>' is not assignable to type 'this'.

302   export interface AlternativesSchema<N = any> extends Joi.AnySchema {

This is isolated because commenting the when section has no other tsc issues. Can someone help with this typescript error?

TCMiranda commented 4 years ago

Thanks @ChrisCrewdson we can fix your error with this: https://github.com/ChrisCrewdson/joi-extract-type/pull/1

TCMiranda commented 4 years ago

Did you try not to move outside Joi namespace? To prevent this breaking change?

TCMiranda commented 4 years ago

Hey guys, after some tests, I couldn't find a way to make the extraction without working on the same Joi namespace.

This is because we need to augment Joi methods to generate the types in the first place. When we do Joi.object() it needs to generate the generic in the background. Working on another namespace (like JoiExtract) prevents this.

Nowadays, Joi types export a Joi.Root interface containing those methods, but for some reason they don't merge the same way as before.

Here is an example. When I do something like:

import '@hapi/joi';
declare namespace Joi {
  export type sometype = boolean
}

I cant find Joi.sometype as I could before.

And when I do:

import '@hapi/joi';
declare module '@hapi/joi' {
  namespace Joi { // with or without the namespace
    type test = StringSchema
  }
}

I get Exported type alias 'test' has or is using private name 'StringSchema'.ts(4081) Which means I can't access StringSchema. Even after I exported the schemas within @types/hapi__joi.

Anyone has any idea why this is happening? Or how to deal with it?

TCMiranda commented 4 years ago

I pushed a branch trying to merge the Root interface: https://github.com/TCMiranda/joi-extract-type/blob/feature/chris-joi16-namespace-fix/index.ts#L443

TCMiranda commented 4 years ago

@guyellis just pinging you here to focus the conversation on this approach

azai91 commented 4 years ago

Any update on this PR?

TCMiranda commented 4 years ago

No updates. I don't this that this approach will solve the issue @azai91

RatTac commented 4 years ago

Just wondering: Wouldn't it be a solution to move extractType outside the Joi namespace? I think support for Joi version 16+ would be more important than backwards compatibility for this breaking change.

TCMiranda commented 4 years ago

Unfortunately, we need another approach for @16, I'll close this for now to focus on the issue #22 Thanks