You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Should mapped types where the result is never filter keys? #23199
I am not sure that this is a bug but it did behave in a way that I did not expect which is why I filed a new issue. If this is not a bug it should probably be closed and continued in earlier issues like #17678
Related Issues:
If this have worked as expected #17678 would be already be supported. That issue is marked as a duplicate and linked to #12424 and #17636 but I am not sure I see the direct relation there to be honest.
Technically a type with at least one property of type never is itself never; since there is no run time value that can satisfy that type, and this is it the empty type (i.e. never).
that said, the way the compiler defers getting the types of properties. this is the only way really to reason about structural types and recursive types without chocking. so when an type is created, the compiler only knows about its properties, and not their types. it only compute the property types when it needs to. needing to do this filtering means that when a type is created the compiler needs to figure out its property types to know whether to add the property or not.
You can achieve what you were looking for by first filtering the keys, then creating a mapped type from the filtered keys.. e.g.:
typeFilteredKeys<T,U>={[PinkeyofT]: T[P]extendsU ? P : never}[keyofT];typeApples={[QinFilteredKeys<Fruits,Apple>]: Fruits[Q]};
Reacted by ulrichb, Kris Kaczor, Spencer Yue, Andrei Picus, Máté Solymosi, cpprookie, chun shang, Malcolm Kee, Jules Sam. Randolph, Brian Le and 25 more
Reacted by Hassan Hedr, Qwerty (Vítězslav Ackermann Ferko), Salvatore, Jules Sam. Randolph, Sean Matheson, Jelmar Gerritsen, Roger Padilla and Luis Arias
Reacted by Jono Job, ulrichb, Sylvain Estevez, Máté Solymosi, Kyle Cannon, Jules Sam. Randolph, Jelmar Gerritsen, Roger Padilla, whale9490, Jason Miller and 1 more
Reacted by Erik, Roger Padilla, Jason Miller, Jay Bhatt and Andrew Morris
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
there is a difference between { b: string | undefined } and { b?: string } - in the former case you can't just omit the property, you have to specify it as undefined
Reacted by Eduard Jacko, Ankur Oberoi, Mateusz Kasprzak and Andrew Kaiser
Activity
mhegazy commentedon Apr 6, 2018
Technically a type with at least one property of type
neveris itselfnever; since there is no run time value that can satisfy that type, and this is it the empty type (i.e. never).that said, the way the compiler defers getting the types of properties. this is the only way really to reason about structural types and recursive types without chocking. so when an type is created, the compiler only knows about its properties, and not their types. it only compute the property types when it needs to. needing to do this filtering means that when a type is created the compiler needs to figure out its property types to know whether to add the property or not.
You can achieve what you were looking for by first filtering the keys, then creating a mapped type from the filtered keys.. e.g.:
typescript-bot commentedon Apr 21, 2018
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
ulrichb commentedon May 4, 2018
Nice! Has the same issue and this solves it. Thanks!
alexfoxgill commentedon Jul 26, 2018
unfortunately this does not seem to preserve optional members:
there is a difference between
{ b: string | undefined }and{ b?: string }- in the former case you can't just omit the property, you have to specify it asundefinedkresli commentedon Mar 23, 2019
also it doesn't work with generics at all
playground
https://www.typescriptlang.org/play/#src=%0D%0Ainterface%20ISimpleString%20%7B%0D%0A%20%20%20%20value%3A%20string%3B%0D%0A%7D%0D%0Ainterface%20ISimpleNumber%7B%0D%0A%20%20%20%20value%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20ModelPropertiesDeclaration%20%7B%0D%0A%20%20%20%20%5Bkey%3A%20string%5D%3A%20ISimpleString%0D%0A%7D%0D%0A%0D%0Atype%20IModelType%3CP%20extends%20ModelPropertiesDeclaration%3E%20%3D%20%7B%7D%0D%0A%0D%0Atype%20FilteredKeys%3CT%2C%20U%3E%20%3D%20%7B%20%5BP%20in%20keyof%20T%5D%3A%20T%5BP%5D%20extends%20U%20%3F%20P%20%3A%20never%20%7D%5Bkeyof%20T%5D%3B%0D%0A%0D%0A%2F%2F%20%3D%3D%3D%3D%3D%0D%0A%2F%2F%20Test%0D%0A%2F%2F%20%3D%3D%3D%3D%3D%0D%0A%0D%0Ainterface%20TestModel%20%7B%0D%0A%20%20%20%20label%3A%20ISimpleString%2C%0D%0A%20%20%20%20age%3A%20ISimpleNumber%0D%0A%7D%3B%0D%0A%0D%0Atype%20BuildFromPropsC%20%3D%20IModelType%3C%7B%0D%0A%20%20%20%20%5BK%20in%20FilteredKeys%3CTestModel%2C%20ISimpleString%3E%5D%3A%20TestModel%5BK%5D%20%2F%2F%20%3C--%20this%20works%0D%0A%7D%3E%0D%0A%0D%0Atype%20BuildFromProps%3CP%20extends%20TestModel%3E%20%3D%20IModelType%3C%7B%0D%0A%20%20%20%20%5BK%20in%20FilteredKeys%3CP%2C%20ISimpleString%3E%5D%3A%20P%5BK%5D%20%2F%2F%20%3C--%20doesn't%20work%0D%0A%7D%3E%3B%0D%0A%0D%0A
turolla commentedon May 13, 2020
Hi, here is another example where
type FilteredKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never }[keyof T];does not work.
https://www.typescriptlang.org/play/index.html#code/C4TwDgpgBAYglgG2BAThAJgaQiAzgHgBUAaKAVQD4oBeKAbygG0AFKOAOygGscB7AMyiEAugC4hLYVAgAPZO3S5yUAPxRW49hABuqKAF9GPEAKHCA3AFgAUDYD0dqAFoXNjshT8AhgGNoAIS8UGABXdh9gOF52Iio6GyhEqAAKCJlxAGFo5DlYgEpxL3YQK2t9N3YPbz8oQJQAGS8AIwgEegSkhGbW8QByJqDe0vLrUEhaoPwYaTkIBSU60PDI6PwikAoqWmmAMgmG7oRSm3tHFycKqt9oLMrZYFj26ySoAZRccTqCQgobEZsxgEgt8tk8Xg4mMY2JxjKYRJ8ggBJZAAWyIRhwwioUAh+BcUGAAAs4EoAO68FBcXAdRIYkDQ2CIDwYbB4IikOqNFoIChifbIiBowh0rGJXH4wjEpToXgQXDsXrAKDkyl-E6jcBAlACoWgwgzeSKMFJZIAOnNQQA5oVioxhAVofw9AAlUovLrcvpvIZ-VRQZ1QTQ6VDHawQ842HxdXBKGC8XjGxJgFC8ZARDBQLzodB1KYGuZGxZhCJRGJEkmbZL8djiGAO3MwOI0l5QNDAEIoThhdAQfgcDAAQnMUGbI3+tjDjkIAFEAMqEdVRrwx2DxgCM+fmq4T8WeSX4AAYaFAD279xvaOXcKaszmgqlgDIaFQ13kz4l+AAmY9Xm-ZuoPk+1BNnuLZQD40S4Eq6BeMAXjHmkppvNe-BrqawC8LOwAoBwlrJG+OKOHiTiwF4iBKISqAQKOb5qhOgLbmutw5EqtDMfcUzrhQw6RpBSppGutbruxcjHt2vb9ugQ68ewUFQKhCGPmhyGmqh6GYdhuH4aGQA
simeyla commentedon Aug 14, 2021
TypeScript 4.1 - Key Remapping
Typescript 4.1 has a new feature Key Remapping.
You can now do the following:
And yes, if you produce
never(for the key) the property will be filtered out.