ITADN

Inferred type of `TObject.required` is incorrect for types with arbitrary properties

#1608Closedrobby-cornelissen 创建于 2026-06-09
When creating a type alias for an object with arbitrary `properties`, the type of the inferred `required` property is incorrect. In the following example: ```typescript type R = TObject<{ [key: PropertyKey]: TSchema }>['required']; ``` The type of `R` is inferred as `[string]`, instead of the expected `string [] | undefined`. This behavior is due to how [`TRequiredArray`](https://github.com/sinclairzx81/typebox/blob/5fa3c9dca3dc0cf0662ff9e7a66ee7e0fb07d19f/src/type/types/properties.ts#L78) is defined: ```typescript export type TRequiredArray<Properties extends TProperties, RequiredProperties extends TProperties = { [Key in keyof Properties as Properties[Key] extends TOptional<Properties[Key]> ? never : Key] : Properties[Key] }, RequiredKeys extends string[] = TUnionToTuple<Extract<keyof RequiredProperties, string>>, Result extends string[] | undefined = RequiredKeys extends [] ? undefined : RequiredKeys > = Result ``` The most straightforward (although arguably not the cleanest) solution would be to accommodate for this case explicitly, and update `TRequiredArray` as follows: ```typescript export type TRequiredArray<Properties extends TProperties, RequiredProperties extends TProperties = { [Key in keyof Properties as Properties[Key] extends TOptional<Properties[Key]> ? never : Key] : Properties[Key] }, RequiredKeys extends string[] = TUnionToTuple<Extract<keyof RequiredProperties, string>>, Result extends string[] | undefined = RequiredKeys extends [] ? undefined : [string] extends RequiredKeys ? string[] | undefined : RequiredKeys > = Result ``` This causes 1 test in [typebox/test/typebox/runtime/type/engine/action/pick.ts](https://github.com/sinclairzx81/typebox/blob/2502e97dccc18e1c10e42c75d89e84b6946c0c5d/test/typebox/runtime/type/engine/action/pick.ts#L128) to fail compilation, because for some reason the compiler now correctly determines that `Type.TObject<{ x: Type.TOptional<Type.TNumber>; y: Type.TString; z: Type.TOptional<Type.TBoolean> }>` is indeed not assignable to `Type.TObject<{ x: Type.TNumber; y: Type.TString; z: Type.TBoolean }>` because of the difference in their `required` properties. All other 34867 tests compile and pass. If you're willing to review this, I'm open to taking directions and preparing a pull request.
关闭于 2026-06-09 1 条评论