TS- tuples are converted to objects
Topic link
Pass in a tuple type and convert the tuple type to an object type whose keys/values are iterated from the tuple.
Such as:
const tuple = ['tesla'.'model 3'.'model X'.'model Y'] as const
const result: TupleToObject<typeof tuple>
// expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
Copy the code
I. Key word description
tuples
Tuple official link
In TypeScript, tuple types are used to represent arrays with known numbers and types of elements. Each element does not have to be of the same type.
Arrays merge objects of the same type, while tuples merge objects of different types.
An ancestor can be used to determine the data type of an element, but do not go beyond the scope. A primitive can be thought of as a fixed length, and beyond the scope does not guarantee its type.
The typeof keyword
In TypeScript, the typeof operator can be used to retrieve the typeof a variable or object.
interface People {
name: string;
age: number;
}
const me: People = { name: "zzk".age: 23 };
type Me = typeof me; // type Me = People
Copy the code
In the above code, we get the typeof the me variable using the typeof operator and assign it to the me variable, after which we can use the me type:
const oneGod: Me = { name: "one".age: 24 }
Copy the code
You can do the same for nested objects:
const otherPeople = {
name: "one".age: 24.address: {
province: 'shandong'.city: 'Qingdao'}}type OtherPeople = typeof otherPeople;
/* type OtherPeople = { name: string; age: number; address: { province: string; city: string; }; } * /
Copy the code
In addition to retrieving the structural typeof an object, the typeof operator can also be used to retrieve the typeof a function object, for example:
function toArray(x: number) :Array<number> {
return [x];
}
type Func = typeof toArray; // -> (x: number) => number[]
Copy the code
The as keyword
Type assertion official link
Sometimes you’ll find that you know more about a value than TypeScript does. Usually this happens when you clearly know that an entity has a more exact type than its existing type.
Type assertions are a way of telling the compiler, “Trust me, I know what I’m doing.” Type assertion is like conversion in other languages, but without special data checking and deconstruction. It has no run-time impact, only at compile time. TypeScript assumes that you, the programmer, have done the necessary checks.
Type assertions come in two forms. The first is the Angle bracket syntax:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
Copy the code
The other is the as syntax:
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
Copy the code
Both forms have the same effect; However, when you use JSX in TypeScript, only AS syntax assertions are allowed.
Const assertion
TypeScript 3.4 introduces a new way of constructing literals, also known as const assertions. When we construct new literal expressions using const assertions, we can signal to the programming language the following:
- No literal type in an expression should be extended;
- Object literal property that will be used
readonly
Modification; - The array literal will become
readonly
Tuples.
Here’s an example of a const assertion:
let x = "hello" as const;
type X = typeof x; // type X = "hello"
let y = [10, 20] as const;
type Y = typeof y; // type Y = readonly [10, 20]
let z = { text: "hello" } as const;
type Z = typeof z; // let z: { readonly text: "hello"; }
Copy the code
When a const assertion is applied to an array literal, it becomes a readonly tuple. After that, we can also use the typeof operator to get the union typeof the element values in the tuple as follows:
type Data = typeof y[number]; // type Data = 10 | 20
Copy the code
The same applies to arrays containing reference types, such as arrays containing ordinary objects. Here’s a concrete example:
Const locales = [{locale: "zh-cn ", language:" Chinese "}, {locale: "en", language: "English"}] as const; // type Locale = "zh-CN" | "en" type Locale = typeof locales[number]["locale"];Copy the code
There are two additional considerations when using const assertions:
const
Assertions apply only to simple literal expressions
// A 'const' assertions can only be applied to references to enum members, // or string, number, boolean, array, Or object literals.let a = (math.random () < 0.5? 0 : 1) as const; // error let b = math.random () < 0.5? 0 as const : 1 as const;Copy the code
const
Context does not immediately convert the expression to be completely immutable
let arr = [1, 2, 3, 4]; let foo = { name: "foo", contents: arr, } as const; foo.name = "bar"; // error! foo.contents = []; // error! foo.contents.push(5); / /... works!Copy the code
Two, the use of tuples
Define a pair of tuples of string and number:
let tom: [string.number] = ['Tom'.25];
Copy the code
When assigning or accessing an element with a known index, the correct type is obtained:
let tom: [string.number];
tom[0] = 'Tom';
tom[1] = 25;
tom[0].slice(1);
tom[1].toFixed(2);
Copy the code
You can also assign only one of the items:
let tom: [string.number];
tom[0] = 'Tom';
Copy the code
However, when a tuple type variable is initialized or assigned directly, all items specified in the tuple type need to be supplied.
let tom: [string.number];
tom = ['Tom'.25];
let tom: [string.number];
tom = ['Tom'];
// Property '1' is missing in type '[string]' but required in type '[string, number]'.
Copy the code
Out of bounds element
When an out-of-bounds element is added, its type is limited to the combined type of each type in the tuple:
let tom: [string.number];
tom = ['Tom'.25];
tom.push('male');
tom.push(true);
// Argument of type 'true' is not assignable to parameter of type 'string | number'.
Copy the code
Third, antithesis
const tuple = ['tesla'.'model 3'.'model X'.'model Y'] as const
// ReadOnly, extends: When a const literal represents an object literal property, the property is modified with 'readonly'. Array literals become 'readonly' tuples. No literal types in expressions should be extended
//[K in T[number]] loop through each index in the array to convert index to key
type TupleToObject<T extends readonly any[]> = { [K in T[number]]: K }
const result: TupleToObject<typeof tuple>
// expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
Copy the code