Skip to content
New issue

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

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

Already on GitHub? # 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.

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

Successfully merging a pull request may close this issue.

3 participants