Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript 4.9 satisfies does not properly enforce enum on SomeJTDSchemaType #2205

Open
sinderw opened this issue Jan 25, 2023 · 4 comments · May be fixed by #2206
Open

Typescript 4.9 satisfies does not properly enforce enum on SomeJTDSchemaType #2205

sinderw opened this issue Jan 25, 2023 · 4 comments · May be fixed by #2206

Comments

@sinderw
Copy link

sinderw commented Jan 25, 2023

Ajv version 8.12.0

Typescript 4.9 allows us to use the satisfies operator, which can be used to enforce the correctness of a schema through SomeJTDSchemaType before sending it to JTDDataType:

const schema1 = { type: 'string' } as const satisfies SomeJTDSchemaType;

type Schema1 = JTDDataType<typeof schema1>;

// No error, Schema1 = string as expected


const schema2 = { type: 'something_else' } as const satisfies SomeJTDSchemaType;

type Schema2 = JTDDataType<typeof schema2>;

// Error on the `satisfies SomeJTDSchemaType`, as expected:
//   Type '{ readonly type: "something_else"; }' does not satisfy the expected type 'SomeJTDSchemaType'.
//   Types of property 'type' are incompatible.
//   Type '"something_else"' is not assignable to type '"boolean" | NumberType | StringType | undefined'.

This feature does not work properly with enum types:

const schema3 = { enum: ['apple', 'banana'] } as const satisfies SomeJTDSchemaType;

type Schema3 = JTDDataType<typeof schema3>;

// Although this should be fine, we have an unexpected error on `satisfies SomeJTDSchemaType`:
//   Type '{ readonly enum: readonly ["apple", "banana"]; }' does not satisfy the expected type 'SomeJTDSchemaType'.
//   Types of property 'enum' are incompatible.
//   The type 'readonly ["apple", "banana"]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.

In fact, in types/jtd-schema.ts:14, we see that SomeJTDSchemaType contains {enum: string[]}, to which readonly [...] cannot be assigned to.

This seems fixable by simply changing the enum type in this file to {enum: readonly string[]}.

Can I open a PR for that?

@epoberezkin
Copy link
Member

I don't see any downside to it, should be ok. Thank you.

cc @erikbrinkman

@epoberezkin
Copy link
Member

if it works ok, probably worth adding to tests / examples (once 4.9 is not the latest version:)

@sinderw
Copy link
Author

sinderw commented Jan 25, 2023

Sorry, I meant that satisfies was added in 4.9, but the bug is reproduced here in 4.9.4, latest typescript version

As this bug is purely related to typescript types, unless I am mistaken, I don't see a place to add relevant tests?

JTDDataType was not really documented in the doc, so I added a presentation with examples the same way it was done for JTDSchemaType; in which I documented the use of satisfies

@entropitor
Copy link

@epoberezkin Is there anything that still needs to be done to merge this in? It would be a super useful addition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants