Tip: After the article is written, the table of contents can be automatically generated. How to generate it can refer to the help document on the right
Typescript high-level key-value type and the difference between type and interface
Recommended website for essential front-end tools (free picture bed, API, ChatAI and other practical tools):
http://luckycola.com.cn/
Preface
Learning objectives:
1. The syntax of key-value types
2. The difference between type and interface
3. Summary of some usage scenarios of type aliases and interfaces
1. Syntax of key-value types
1. Grammar
// 键值类型语法
{
[key: KeyType]: ValueType }
// 注意在键值语法中KeyType类型只能是string、number、symbol或则模板字面量 不能是纯字面量
2. Error examples
// 错误例子
interface Dictionary {
[key: boolean]: string;// 错误 keyType不能是boolean
};
// 模板字面量例子
interface ProChangeHandler {
[key: `${
string}Changed`]: () => void;// 正确
};
let handlers: ProChangeHandler = {
idChanged: () => {
},
nameChanged: () => {
},
ageChange: () => {
}, // 错误 不符合模板字面量规定的格式 少一个字符d
}
// 使用字面量的错误例子
interface User1 {
[key: 'id']: string; // 错误 keyType不允许是字面量类型
}
interface User2 {
[key: 'id' | 'age']: string; // 错误 keyType不允许是字面量类型
}
// 解决以上问题可以如果Record这个工具类型
type User3 = Record<'id', string>; // 正确
type User4 = Record<'id' | 'age', string>; // 正确
3. Correct example
// keyType是string类型时中括号取值
interface NumberNams {
[key: string]: string;
}
let names: NumberNams = {
'1': 'name',
2: 'age', // 正确 在对象中属性都会经过隐式转换变成 string
};
const name = names['1']; // 正确
const name2 = names[1]; // 正确 会经过隐式转换变成 string
type N0 = keyof NumberNams; // 注意结果是 string | number,这说明由于隐式转换的作用在keyType中 string、number类型是兼容的
2. The difference between type and interface
1. Same point one
The code is as follows (example):
// 1.相同点一:类型别名和接口都可以用来描述对象或函数
// type
type Ponit = {
x: number;
y: string;
};
type SetPonit = (x: string) => void;
// interface
interface Ponit2 {
x: number;
y: string;
};
interface SetPoint2 {
(x: number): number;
};
let fn1: SetPonit = (x: string) => {
};
let fn2: SetPoint2 = (x: number): number => {
return 1 };
2. The same point two
The code is as follows (example):
// 2.相同点二:类型别名和接口都支持拓展
// type通过交叉运算拓展
type Animal = {
name: string;
};
type Dog = Animal & {
age: number };// {name: string;age: number};
// interfcae通过extends继承拓展(支持多继承)
interface Animal2 {
name: string;
};
interface Cat extends Animal2 {
color: string;
};// {name: sting;color: string;}
// 同时type和interface也支持一起使用来进行拓展
type Perple = {
name: string;
};
interface Person {
age: number;
}
type P1 = Perple & Person;// {name; string;age: number};
interface P2 extends Perple {
color: boolean;
};// {color: boolean; name: string}
4. Difference 1
// 不同点:同名接口会自动合并,而别名不会
// 基于这个特性常常在项目中用于拓展第三方模块的类型
// interface
interface User1 {
name: string;
};
interface User1 {
age: number;
}
// 所以最终的User1是{name: string;age: number};
// type
type User2 = {
name: string;
};
type User2 = {
age: number;
}// 报错 别名定义重复
3. Summary of some usage scenarios of type aliases and interfaces
Scenarios for using type aliases
- When defining an alias for a basic type, use type
- When defining a tuple type, use type
- When defining a function type, use type
- When defining a union type, use type
- When defining a mapping type, use type
Scenarios for using the interface
- When taking advantage of the automatic merging feature of interfaces, use interface
- When defining an object type and no type is required, use interface