[ts] Typescript high-level: key-value type and the difference between type and interface

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


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

  1. When defining an alias for a basic type, use type
  2. When defining a tuple type, use type
  3. When defining a function type, use type
  4. When defining a union type, use type
  5. When defining a mapping type, use type

Scenarios for using the interface

  1. When taking advantage of the automatic merging feature of interfaces, use interface
  2. When defining an object type and no type is required, use interface

Summarize

Guess you like

Origin blog.csdn.net/qq_48896417/article/details/125111363