-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Indexed Access Types.md #2603
base: v2
Are you sure you want to change the base?
Conversation
The documentation wrongfully states that a constant cannot be used to index, but that's not true, as this is caused by a misfitting type that could be solved by using 'as const'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement!
Is something wrong with the tests? |
const key = "age"; // Type is 'string' | ||
type Age1 = Person[key]; | ||
|
||
const keyWithConstantType = "age" as const; // Type is "age" | ||
type Age2 = Person[keyWithConstantType]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused by this; aren't both invalid? Is that what you're trying to show here? Isn't the problem not to do with const
, but that you can't index a type with something in value space, and therefore need to typeof
something or use a type?
I would think that if anything, the old stuff could stay, but instead say something like:
You can only use types when indexing. For example, you cannot index a type with a variable:
And maybe include a typeof
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Example 1
type Age1 = Person["age"]; // Success
// Example 2
const key2 = "age";
type Age2 = Person[key]; // Failure
// Example 3
const key3 = "age" as const;
type Age3 = Person[key]; // Success
In example 1 above, "age"
can be used to index Person
as it's one of Person
's keys.
In example 2 above, the reason why key2
fails - is because the TypeScript type of key
is string
, and it's too wide for a key of the Person
type.
For example: bla
is a valid string but it's not a key of Person
, and therefore key2
is not fit to index Person
.
For that reason, the existing documentation says users should use a constant as an index.
In example 3 above, the reason why key3
succeeds - is that the TypeScript type of key
is "age"
(and not string
), which is a key of the Person
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've edited my PR to be more self-explaining
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I apparently missed the push.
What I'm saying is that it isn't behaving the way you're describing; your third example fails to compile: Playground Link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue isn't as const
, the issue is you need to use typeof key2
and typeof key3
: Playground link
While Computed Property Names in Object Type Literals and Interface Types use values, Indexed Access Types can only use types:
interface List<T> {
[Symbol.iterator](): Iterator<T>;
// ^^^^^^^^^^^^^^^-- 'Symbol.iterator' here used as a value
}
type ListIterator = List<number>[typeof Symbol.iterator];
// ^^^^^^-- must use 'typeof' here to read its type
I think the original statement is mostly accurate ("you can't use a
|
The documentation wrongfully states that a constant cannot be used to index, but that's not true, as this is caused by a misfitting type that could be solved by using 'as const'.