Issue
Just found following code snippet in https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types
type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
what [keyof T]
after type declaration means and how it is named?
Also [keyof T]
looks like a hint for a compiler that keys in FunctionalPropertyNames
are keys from T, but why can not compiler infer this from [K in keyof T]
?
Solution
Short explanation: This usage, gets all the value types of all properties.
First of all, []
after a type drills into that type by accessing that type with a key (or keys)
type A = { foo: string }
type B = A['foo'] // string
Second, you have a mapped type here. That means it's a type that maps over all keys of some type, transforms it, then returns a new type.
So lets look at this part on it's own first:
type StripNonMethods<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}
Whatever T
is, this will make a type that for all keys of T
where the value of each property is either the name of the property (if the value is a function) or never
(if it's not a function).
This would transform this:
type T1 = { a(): void, b: number }
into:
type T2 = StripNonMethods<T1> // { a: 'a', b: never }
But the desired result here is the string 'a'
, because we are trying to get all property names that are functions. So we drill in to this type with it's own keys, which returns all values of all properties as a union with [keyof T]
at the end.
This would now return:
type T3 = T2[keyof T2] // 'a' | never
And because never
can never exist, by definition, it's simplified out of the union and you just get:
'a'
Answered By - Alex Wayne
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.