TypeScript associative types
Joint type refers to a variable has a variety of possible types, a variety of types with symbol between | segmentation can be a base type:
let content: string | number = "content"; // Content can be either a string or a number
content = 123;
Copy the code
It can also be an object type:
interface Student {
sid: string
name: string
}
interface Teacher {
tid: string
subject: string
}
let man: Student | Teacher = { // Man can be a Student or a Tacher
sid: '1001'.name: 'XiaoCai'
}
man = {
tid: '2001'.subject: 'sports'
}
Copy the code
TypeScript type protection
As type assertion
When a variable has more than one possible type, the AS keyword is used to determine the type
interface StrProp {
isStr: boolean
name: 'String'
}
interface NumProp {
isStr: boolean
age: 18
}
function say(arg: StrProp | NumProp) {
// console.log(arg.name) // An error was reported
if(arg.isStr) {
// When the isStr attribute of arg is true, we conclude that arG is of type StrProp
console.log((arg as StrProp).name)
} else {
console.log((arg as NumProp).age)
}
}
Copy the code
In grammar,
We can also determine the type of a variable by determining whether it has a property by using in
interface StrProp {
isStr: boolean
name: 'String'
}
interface NumProp {
isStr: boolean
age: 18
}
function say(arg: StrProp | NumProp) {
if('name' in arg) {
console.log(arg.name)
} else { // TypeScript automatically determines the else part here
console.log(arg.age)
}
}
Copy the code
Typeof grammar
function test(arg: string | number) {
if(typeof arg === 'string') {
return arg.split(' ')}else {
return 2 * arg
}
}
Copy the code
Enum Enum type
Enumerated types are commonly used to define constants
// enum Sex {// Enumeration type can not initialize the value, the default value is 0
// MALE,
// FEMALE,
// UNKNOW
// }
enum Sex {
MALE = 1.// Can be given a starting value, automatic increment
FEMALE,
UNKNOW
}
function checkSex(sex: Sex) {
let result = ' ';
switch(sex) {
case Sex.MALE:
result = 'male';
break;
case Sex.FEMALE:
result = 'woman';
break;
case Sex.UNKNOW:
result = 'unknown';
break;
default:
break;
}
return result;
}
console.log(checkSex(1)) / / 'male'
Copy the code
Generic TypeScript
The concept of generics
If you want to implement a function whose return value type is the same as the parameter type, you can write:
function fun(arg: string) :string {
return arg
}
Copy the code
Or this:
function fun(arg: number) :number {
return arg
}
Copy the code
But these are too limited to be true for all cases, so you can use generics. Generics are generic types, defined by <>, usually with a single capital letter like
function fun<T> (arg: T) :T {
return arg // The return value type is the same as the parameter type
}
Copy the code
Generic array
Two ways to write generic arrays
/ / T []
function fun<T> (arg: T[]) :T[] {
return arg.reverse()
}
fun<string>(['a'.'b'.'c'.'d'])
// fun(['a', 'b', 'c', 'd']) generics also support type inference
// Array<T>
function func<T> (arg: Array<T>) :Array<T> {
return arg.reverse()
}
func<number>([1.2.3.4.5])
Copy the code
Multiple generic definitions
Generics can define more than one, similar in usage to one
function fun<T.P> (first: T, second: P) :T.P] {
return [first, second]
}
fun<string, number>('string'.123)
Copy the code
Inheritance in generics
Generics can be constrained by inheritance
interface Key {
key: number
}
function fun<T extends Key> (arg: T) :T { // The generic T inherits the interface Key, so the parameter must contain the Key attribute
return {
...arg,
key: new Date().getTime() + arg.key
}
}
fun({
key: 123.name: 'test'
})
Copy the code
Simple use of generics
Implement an AXIos method that accepts both url and payload parameters. The type of the received parameter and the return value are different depending on the URL
interface Todo {
// Todo interface
id: number;
name: string;
done: boolean;
}
let todos: Todo[] = [
// Initial data
{
id: 1.name: Sb "1".done: false}, {id: 2.name: "Agent 2".done: true,},]; enum Urls {Todo[] todo [] todo []
TODOS = "/api/todos".// Todo state todo interface. The parameter type is number. The return value type is Boolean
TOGGLE = "/api/toggle".// Add the todo interface. The parameter type is todo and the return value type is Boolean
ADD = "/api/add",}// Define a tool type
// Return a custom key based on the generic input value
type Key<U> = U extends Urls.TODOS ? "todos" :
U extends Urls.TOGGLE ? "toggle" :
U extends Urls.ADD ? "add" : "other";
// Obtain the corresponding Key based on the tool type Key, and obtain the corresponding parameter type based on the Key
type Payload<P> = {
todos: any;
toggle: number;
add: Todo;
other: any;
}[Key<P>];
// Obtain the corresponding Key based on the tool type Key and the corresponding result type based on the Key
type Result<R> = {
todos: Todo[];
toggle: boolean;
add: boolean;
other: any;
}[Key<R>];
function axios<T extends Urls> (url: T, payload? : Payload
) :Promise<Result<T>> | never {
let res;
switch (url) {
case Urls.TODOS: // Get toDO data, no arguments, return type todo []
res = todos.slice();
break;
case Urls.TOGGLE: // Change the toDO state with type number and return Boolean
const todo = todos.find(({ id }) = > id === payload);
if(todo) { todo.done = ! todo.done; } res =true;
break;
case Urls.ADD: // Add todo with toDO type and return Boolean type
// add! To allow undefined and NULL to compiletodos.push(payload!) ; res =true;
break;
default:
throw new Error("Unknow api!");
}
return Promise.resolve(res as any);
}
axios(Urls.ADD, {
id: 3.name: 'Take notes'.done: false
}) // Add a piece of data
console.log(axios(Urls.TODOS)) // Get all data
axios(Urls.TOGGLE, 2) // Switch the done state of data 2
Copy the code