-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Description
Bug Report
π Search Terms
Tuple, variadic tuple, narrowing, parameters, generics, const parameters, readonly
π Version & Regression Information
- This changed between versions 5.0 and 5.1
β― Playground Link
Playground link with relevant code
π» Code
type narrow<def> = def extends string
? def
: def extends [unknown, ...unknown[]]
? def
: {
[k in keyof def]: narrow<def[k]>
}
declare const parse: <def>(def: narrow<def>) => def
const result = parse([{ a: "foo" }])
// ^?
// <5.1: [{a: "foo"}]
// 5.1: [{a: string}]
Description
During the pre const
generic parameter-era, patterns similar to this one became widely used for narrowing an array input to a tuple. This particular case has been simplified down from ArkType's parser, but as you can see it is very easy to reproduce and it seems possible it could break existing functionality in other libraries.
The workaround I found for this that supported my use case was to narrow the array input iteratively, like this (simplified):
export type validateTupleLiteral<
def extends readonly unknown[],
result extends unknown[] = []
> = def extends [infer head, ...infer tail]
? validateTupleLiteral<tail, $, [...result, head]>
: result
However this would probably not be intuitive for other users who may be affected by the change, and const
parameters are still new enough that most libraries cannot adopt them yet (though they do fix the problem). @Andarist mentioned he thought it could be related to this change:
https://github.com/microsoft/TypeScript/pull/53709/files