-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Inconsistent compiler behavior with recursive conditional type as variables or parameters #60221
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
Comments
I don't see a TypeScript bug anywhere in here. Your type If I were to try to write code like this, I'd make type StringConstraints = { required?: boolean }
type StringSchema = readonly ["string", StringConstraints]
type ObjectSchema<T extends object | null | undefined> =
readonly ["object", { [P in keyof T]: SchemaFor<T[P]> }]
type SchemaFor<T> =
[T] extends [string | null | undefined] ? StringSchema :
[T] extends [object | null | undefined] ? ObjectSchema<T> :
StringSchema
type AnySchema = StringSchema | ObjectSchema<{}>
type Person = {
name: string | null
}
const schema1 = ["object", {
name: ["string", { required: true }],
}] as const
const schema3: SchemaFor<Person> = ["object", {
name: ["string", { required: true }],
}]
type ValidateSchema<T> = T extends StringSchema ? T :
T extends readonly ["object", infer S extends object] ?
readonly ["object", { [K in keyof S]: ValidateSchema<S[K]> }] :
never;
function validate<const T extends AnySchema>(schema: T & ValidateSchema<T>) {
return []
}
validate(schema1)
validate(schema3)
validate(["object", {
name: ["string", { required: true }],
}]) Maybe I made different decisions from the ones you would make, but at no point here am I seeing something that looks like a bug in the language. You might want to close this issue and ask questions in Discord or Stack Overflow if you can't figure out how to adapt this to your use case. |
It seems like what you want is this type StringConstraints = { required?: boolean }
type ObjectConstraints = { required?: boolean }
type StringSchema = ["string", StringConstraints]
type ObjectSchema = ["object", Record<string, AnySchema>]
type SchemaFor<T> =
[T] extends [string | null | undefined] ? StringSchema :
[T] extends [object | null | undefined] ? ObjectSchema :
never
type AnySchema = StringSchema | ObjectSchema because the There are a lot of schema-like libraries doing stuff like this correctly, e.g. |
Thank you both for your quick replies. @jcalz your ValidateSchema was the key. Closing the issue. |
π Search Terms
recursive conditional type compilation variable parameter
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?#code/FAFwngDgpgBAyiATgSwHYHMDCB7VBnJAQzRDxgF4YBvGRKARwFdk6ATAfgC4YAjbbADZRCqGAF9QkWAHkeAKygBjEDnxESZSjTpMWUDtz6DhoiZOjwkadHEUALKAFtCFGAG0ARARQYPAGksfLFxvYlRSAF1zGXklEFsHZwAeABUYKAAPEChUVjJsWOUYAB8YVEYBARKYRlyoADM0fQA+V08ChWV-ancABRg0GABrKDBsepgUiO4Ep0IAMWxEVLdeiNaxKOj4eznF5ZTWymAYU-cp9KycvPdva2ryyura1gam1giYdkDrWecYTgnM5uC6ZbK5MhuDpxB4VKqlF5vVD6T7fWSdeK7ZKHAFA07IgBuUEQwG2AEFUGA-i5KAggtTqui4tSklQxM1SeALL1iXhcK4qHiyoRHFBuHcMLDKsAzPVaspkPyCYQBMhWIRsgAKPBYwjcClU3UASmoQroIEYiFEbiiZkUIRAMB1iUIAEY2h5oV0AoKzsLRdxPBL0N1tAxmGxuEhGLBNn4ZVt7WonbqAEz6ykMyjtQogUNC1AisXuLxWXw+2jhvSsKOIGPiCLxzakpMEFMugDMM11+ySPMQfNQRxLXrzPoLRcDpaCocrukjMGjscbCdJytV6q1zrmrqNwAA9PuYABRRCIJb6xDoRii8IwcaLqQwADk2rL6GqNELAZgb6Cn7nCN9EMfghBEABucQjRtSCxGgiJnwGMhUGwR1CDwPBkHQQseCERdsBgCBCEQItskQe8Ji5WBnwNalnwAOgPI9JifV9gwA79iz-e5SjDedgN4UCTFg+CRJtRDkGQ1CYHQzDsMIXDYBAAiqJfJllBZNlmgYpi-RSYj0CgR0dCAshU3SIRbxAbUTR4RhHT5S1FFgZwwBgOxCCJGB6igAB3Yl6M1VMOwAFgAVj3YB1zVDUoG1NMTUPGAADkVKfXZFCGawAk4mTckA6sYEUEReBcyToEqfQopVGKt11DtEqPAB1JYhjIdDLmgZR9ACVSMqyyVJPvIZqo3WLNRzDFZySlrEDawjiJAZAVQEMBevShxMvuXzWvyURPVzDxeHssppP5adrCOpYYA8Ezqw8CcfyDd9ZzuhclwbJsIkioA
π» Code
π Actual behavior
Type-checking only works with schema3, where all properties have to be correctly spelled. schema1 gives a compiler error (see code). schema2 can be completely misspelled with no errors. Passing directly a schema as parameter to the
validate
function works partially.π Expected behavior
All four schema definitions should work with correct and complete type-checking.
Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: