好好理理Typescript的类型

33 阅读3分钟

好好理理Typescript的类型

Typescript的类型总的可以分为基础类型和自定义类型。基础类型与平时使用的Javascript中类型分类几乎一致,而自定义类型相比于基础类型就更加的丰富了,需要好好的理理,无论是种类还是使用方式。

基础类型

对于基础类型来说,大部分不需要显性的进行定义,typescript 有着自动定义类型的功能——类型推断

let num: number = 10;
let num = 10;

上面的两种写法的表达的意思是一致的。但是这种类型推断并不是完全适应所有的类型的,不然这写法和JavaScript可就没什么区别了呀!

基本数据类型

基本数据类型包括number​、boolean​、string​、undefined​、null​、symbol​、bigint​。

// 基本数据类型
let num: number = 10;
let bool: boolean = true;
let str: string = 'hello';
let undefinedVar: undefined = undefined;
let nullVar: null = null;
let symbolVar: symbol = Symbol('symbol');

引用数据类型包括object​、array​、date​、regexp​、map​、set​、weakMap​、weakSet​



// 引用数据类型
let obj: { name: string, age: number } = {
  name: '张三',
  age: 18
}
let arr: number[] = [1, 2, 3];
let date: Date = new Date();
let reg: RegExp = /\d+/;
let map: Map<any, any> = new Map(); // map\set\weakMap\weakSet 可以对键或值进行类型分配,需要用到泛型
let set: Set<any> = new Set();
let weakMap: WeakMap<any, any> = new WeakMap();
let weakSet: WeakSet<any> = new WeakSet();

特殊数据类型包括never​、any​、unknown​、void​、tuple​、enum​

let tuple: [number, string, boolean] = [10, 'hello', true]; // 元组,保持类型和数量一致
enum EnumVar {
    A,
    B,
    C
} 
let e: EnumVar = EnumVar.A; // 枚举,


// 特殊数据类型
function neverFunc(): never {
    throw new Error('neverFunc 不能被调用');
} // never 类型表示永远不会有返回值,通常用于抛出异常或无限循环
let anyVar: any = 10; // any 类型表示任意类型,通常用于与旧代码兼容
let unknownVar: unknown = 10; // unknown 类型表示未知类型,通常用于类型断言或类型守卫
let voidVar: void = undefined; // void 类型表示没有任何类型,通常用于函数没有返回值

自定义数据类型

自定义数据类型就是通过关键字、关键符号、接口、范型对基本数据类型的拓展变化。

类型也有集合的某些概念,其中包括了联合类型和交叉类型。

  • 联合类型:表示一个值可以是多种类型,或的概念,通过符号|​实现。

    let value : string | number;
    value = 'hello';
    value = '18'
    
  • 交叉类型:表示一个值同时具有多种类型,和的概念,通过符号&​实现。

    interface Age {
    	age: number
    }
    
    interface Name {
    	name: string
    }
    
    type Person = Age & Name
    
    const p: Person = {
    	age: 18,
    	name: 'ErMao'
    }
    
​type​定义类型

通过使用type​创建新的组装后的类型。

type Key = string | number | symbol;
Interface​接口定义类型
interface Age {
	age: number
}
泛型​定义类型

泛型定义类型是通过创建可重用的组件,使组件不仅能够使用一种数据类型,而是能够通过传入的参数决定具体的数据类型。这有点像函数中定义的形参和实参。

泛型使用一般分为泛型函数和泛型接口。

  • 泛型函数

    function add<T,U> (a: T, b:U) : T {
    	return a + b
    }
    
    let str = add<string,string>("a","b"); //显性传递
    let num = add(1,2) //类型推断
    
  • 泛型接口

    interface InterfaceVar<T> {
        name: T;
    }
    
    const interfaceVar: InterfaceVar<string> = {
        name: '张三',
    }
    
  • 泛型类

    // 泛型类
    class InterfaceClass<T> {
        name: T;
        constructor(name?: T) {
            this.name = name;
        }
    }
    
    const interfaceClass = new InterfaceClass('张三');
    
  • 泛型约束

    ​extends​(拓展),这里使用泛型约束的命名方式,也是代表了约束了类型是要某一种类型的子类型。同时关键字extends 代表拓展的意思,也能明白,是从另外一个类型中拓展出来的子类型。

    interface Lengthwise {
    	length: number;
    }
    
    function handleLength<T extends Lengthwise> (arg: T): T {
    	console.log(arg.length)
    	return arg;
    }
    
    handleLength({length: 10})
    handleLength(3) // 报错,number 类型没有 length 属性。