TypeScript Version: 4.1.0-beta
Using the new key remapping feature, with a remapped object with never keys (for omitting). Passing the remapped object to keyof returns never, instead of the keys from the remapped object. Checks with the remapped object _itself_ work as expected - its only when then using keyof do they fail.
Search Terms:
Code
type Example = {foo: string, bar: number}
type PickByValueType<T, U> = {
[K in keyof T as T[K] extends U ? K : never]: T[K]
}
type T1 = PickByValueType<Example, string>
const e1: T1 = {
foo: "hello"
}
type T2 = keyof T1
const e2: T2 = "foo"
Expected behavior:
keyof T1 should be "foo"
Actual behavior:
keyof T1 is never
T1 correctly picks out the expected keys based on the condition check, but when ran through keyof it seems to lose the "set" keys.
Playground Link:
https://www.typescriptlang.org/play?ts=4.1.0-pr-40336-88&ssl=4&ssc=41&pln=4&pc=46#code/C4TwDgpgBAogHgQwLZgDbQLxQN4DMD2+AXFAM7ABOAlgHYDmANFAEYIUk0CuSzEFAvgCgoUQaEhQAClQDGAawBCIAGoJUnCABVwEADyamAVQB8ULNmFQA2gGkotKHIgh8uKJqgJS72wF0oEHDAEDQAJt6GUAD8UHYcEABufL4kmn6CQmI67gCMZlKyiipqGtqQuvDIaBBM5NT0xoIy+DTkATmpeeaWIgTEUABEABYQqKj4AxlZEpoATPlOLm6aOU0tbRCzqfNYA32TQA
Related Issues:
Ah, the issue here is that the conditional type in the as clause is not distributive, so when applied to a union type (which we do in getIndexType) it isn't applied to each key individually. A workaround is this:
type PickByValueType<T, U> = {
[K in keyof T as K extends K ? T[K] extends U ? K : never : never]: T[K]
}
But of course it should work without the explicit distribution trick.
Thanks for sharing the workaround @ahejlsberg ! I see there's an open PR for a fix, so I hope the bug report was useful. And thanks for the addition of the feature -- I've already two scenarios where it's proved useful.
Most helpful comment
Ah, the issue here is that the conditional type in the
asclause is not distributive, so when applied to a union type (which we do ingetIndexType) it isn't applied to each key individually. A workaround is this:But of course it should work without the explicit distribution trick.