Author: ICBU Dongmo
Write at the front: welcome to Alibaba ICBU interactive & end technology front end team column, we will share quality front end technology articles with you, welcome to pay attention to & exchange yo!
Preamble: When writing typescript applications, we sometimes want to reuse or construct types of a particular structure that are hard to express from typescript with built-in types, interfaces, and classes.
keyof
In typescript we use the keyof keyword to extract the index tags of objects.
// obj is an object, and typeof gets its type keyof (Typeof obj)Copy the code
The string and number indexes of the object
For ES5, there is no doubt that an index in a hash dictionary can only be a string and a number;
// One simiple object with any type key-value
interface Foo {
[k: string]: any
}
type TFOO = keyof Foo // string | number
Copy the code
The element index of an array has its own special meaning, but it is still of type number.
const a = [] type TA = keyof (typeof a) /** number | "length" | "toString" | "toLocaleString" | "pop" | "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | ... * /Copy the code
Symbol index
Starting with ES6, javascript allows the use of Symbol as an object index
interface objWithSymbol {
foo: string
[Symbol.toStringTag]: any
}
type T_OBJ_WITH_SYM = keyof objWithSymbol // "foo"
const a_with_symkey = {
[Symbol('#symA')]: 'bar'
}
type T_A = keyof typeof a_with_symkey // number | string
Copy the code
At the time of writing, typescript does not support extracting Symbol indexes using the keyof keyword, which is understandable because symbols are often not represented as “keys “. There is no other official way to directly extract an index of the Symbol type in an interface or object type. Symbol has no literal text. The guarantee of its uniqueness is the memory allocation at runtime, not the literal.
In typescript, writing like this violates a type constraint:
Const a = {} // lint: no property 'foo' on type '{}'. ts(2339) a.foo = 'bar'Copy the code
But that won’t:
const a = {}
a[Symbol('#symA')] = 'bar'
Copy the code
Note that Symbol is an index of an Object that does not enumerable: True. And for… In extraction. Similar to get access to an Object string | number type method of the index is the Object. The getOwnPropertyNames (); All Symbol in the access to an Object type Object. The index way getOwnPropertySymbols ();
Extract element types using any as the index
What do we do when we declare an array (of type String []) where all elements are of the same type (for example, string) and we want to get the types of the elements in the array for subsequent variable constraints?
const a: string[] = []
type ELE_A = string
Copy the code
For simple built-in types, we can of course simply declare, or simply declare a as ELE_A[]; And if so?
const a: {a: string, b: string, c: number}[] = []
Copy the code
We can of course declare ELE_A in advance, and then declare a to be ELE_A[]
What if that’s the case?
const a: {a: string, b: string, c: number}[] = []
const a1: {a: string, b: string}[] = []
const a2: {foo: string, c: string}[] = []
Copy the code
If you declare every variable in advance, it feels like writing C: declare first, call later. Using any can help us extract the elements, for example
const a: {a: string, b: string, c: number}[] = []
type T_A = (typeof a)[any]
const a1: {a: string, b: string}[] = []
type T_A1 = (typeof a1)[any]
const a2: {foo: string, c: string}[] = []
type T_A2 = (typeof a2)[any]
Copy the code
In this way, we don’t have to explicitly declare the types of array elements that are reused only once or twice. Instead, we declare variables first and then extract them.
Extract directly from an existing interface
For the following interface, what if I want to extract the type of the element in foo2 (which is an array)?
interface A {
foo: {
foo2: {
foo3: string[]
}[]
}
}
Copy the code
Index directly from A to foo2, then extract its elements using any
type FOO2_ELE = A['foo']['foo2'][any]
Copy the code
❤️ Thank you for seeing the end ~
Alibaba international website (ICBU, Alibaba.com) is the world’s largest cross-border trade and service platform. We have new technical challenges all the time, enough interesting challenges to satisfy all your curiosity and thirst for knowledge, and well-known foreign partners (Google & OpenSky).
If you want to come to ICBU to develop the front end with me, please send your resume to [email protected] and we will respond to your interview arrangement quickly. : -)