wrong behavior about type parameters of `as` clause in a mapped type
🔎 Search Terms
type parameter as mapped type
🕗 Version & Regression Information
5.7.0-dev.20240821
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.7.0-dev.20240821#code/C4TwDgpgBAkgzgZWAJwJYDsDmAeAKgPigF4pcBtAXSggA9gJ0ATOKOFDTSqAfihQFdoALigAzAIYAbOBABQoSFADyAW1TAkaLAGkIIPNToNmUAPYAjAFYQAxsEIkA3rKiuoZbVAxQA1ntOipFDiLPCaHHgeFIS09EwsAtC86BAAbhDIItoUIuTZsgC+srKi-Oh2qKboYnj4ABTAuQCUIo5QjOLA4rlQBVDObnzg0ACCxLCI7Fi1UAD0s+0QohnIEIwubgrQAELjY7HGCciCPHzHwmJSMnMLjEsraxuuW1AAwuNhUziOHV25BWQAOS-cSA6I3RbLZCrdaDVbAfjIaqOPohZRqDRfXT6NognoFQjzKAAAxBxK8LFMGPo6yKQA
💻 Code
type IsString<T> = T[] extends string[] ? true : false
type OmitStringKey<T extends object> = {
[K in keyof T as IsString<T[K]> extends true ? never: K]: T[K]
}
function f<T>(t: T): { data: T } {
type A = IsString<T> // deferred
type B = A extends true ? true : false // deferred
type C = IsString<{data: T}['data']> // deferred
return {} as OmitStringKey<{ data: T }> // `data` is omitted
}
🙁 Actual behavior
OmitStringKey<{ data: T }> omit data property. That means IsString<T> extends true in the as clause is true, while T is not decided yet.
🙂 Expected behavior
type evaluation should be deferred
Additional information about the issue
No response
Perhaps you are misreading the error message? It doesn't exactly mean here that it doesn't have the data property but rather it's not guaranteed that it will have one and your target requires it. I agree that the error could be improved.
Evaluation of this is deferred, the source type (the one that you try to return) there looks like this:
type Source = { [K in keyof {
data: T;
} as IsString<{
data: T;
}[K]> extends true ? never : K]: {
data: T;
}[K]; }
Yeah, an improvement of the error message would be nice.
The fact this raises a type error itself is OK. Nobody knows T is string or not here.
Sorry for rushing to call it a bug