-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
keyof
on types originating from javascript object literals is (nearly) useless
#25987
Comments
keyof
on types originating from javascript object literals is uselesskeyof
on types originating from javascript object literals is (nearly) useless
To be clear, this isn't blocking |
had an offline discussion about this, we should do the right thing and mark the types of JS object literals with a flag to allow for looser property access checking and assignablity checking, instead of manifesting an index signature. |
It is blocking it in JS, yes. |
This is not really specific to JavaScript object literals. That's just a small part of the bigger problem. It's a limitation of I came up with a little helper type that extracts all known keys: type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends {[_ in keyof T]: infer U} ? U : never; This way you don't need to change any type inference. |
Using inference to rebuild the keys sans index signature. Nifty, though very difficult to look at. It can work, though I think I'd have trouble explaining it to anyone. Still - potentially needing to perform such contortions on any type from a js object literal expression seems a bit excessive - it's certainly not what came to my mind as a solution. |
@ajafff Very clever; good work. |
@ajafff Could you please help me understand the type? How exactly is it different from |
@m93a |
I just noticed a little bug in my Here's the fixed version: type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends {[_ in keyof T]: infer U} ? ({} extends U ? never : U) : never; |
@ajafff Doesn't work with typed object literals, any ideas? type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends {[_ in keyof T]: infer U} ? ({} extends U ? never : U) : never;
type SomeType = {
[_:string]: string
}
const foo : SomeType= {
a: 'one',
b: 'two',
}
type MyKeys = KnownKeys<typeof foo> // never |
After upgrading to TS 4.3.2, for some reason it resolves to export type KnownKeys<T> = keyof { [K in keyof T as string extends K ? never : K]: K } |
Compatible with the original version for TS 4: export type KnownKeys<T> = keyof {
[K in keyof T as string extends K ? never : number extends K ? never : K]: never
} |
TypeScript Version: 3.1.0-dev.201xxxxx
Search Terms:
Code
In a js file:
Expected behavior:
keyof
returns the keys the object actually has or is declared with.Actual behavior:
keyof
returnsstring | number
, thanks the the any-index signature shoved into every object literal expression's type in JS.This came up on
DefinitelyTyped
- strongly typing react'spropTypes
is virtually impossible because all of the key filtering and mapping operations (eg,Exclude
) just don't work on any JS object literals (unless all of your keys are unique symbols (nobody would do this, I don't think), since those aren't mangled by subtype reduction with the index signature).cc @mhegazy This is a blocker in rolling out the better React inferences to our JS users.
The text was updated successfully, but these errors were encountered: