Typescript初识&个人评价

933 阅读2分钟

在 2020 年的今天,TS 已经越来越火,不管是服务端(Node.js),还是前端框架(Angular、Vue3),都有越来越多的项目使用 TS 开发,作为前端程序员,TS 已经成为一项必不可少的技能,本文旨在介绍 TS 中的一些高级技巧,提高大家对这门语言更深层次的认知。

接口

interface Person {
    readonly id: string;
    name: string;
    age?: number;
    [propName: string]: any;
}

let tom: Person = {
    id: '996',
    name: 'Tom',
    gender: 'male'
};

评价:在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。

TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述

类型别名

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

评价:类型别名用来给一个类型起个新名字

字符串字面量类型

type EventNames = 'click' | 'scroll' | 'mousemove';
function handleEvent(ele: Element, event: EventNames) {
    // do something
}

handleEvent(document.getElementById('hello'), 'scroll');  // 没问题
handleEvent(document.getElementById('world'), 'dblclick'); // 报错,event 不能为 'dblclick'

评价:字符串字面量类型用来约束取值只能是某几个字符串中的一个。

元组

let tom: [string, number];
tom[0] = 'Tom';
tom[1] = 25;

tom[0].slice(1);
tom[1].toFixed(2);

评价:数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。

枚举

enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};

console.log(Days["Sun"] === 3); // true
console.log(Days["Wed"] === 3); // true
console.log(Days[3] === "Sun"); // false
console.log(Days[3] === "Wed"); // true

评价:枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。

类和接口

评价:因为博主本身是后端转的前端所以这部分相对简单,如果觉得困难的话可以先了解一下Java等后端面向对象的语言。

泛型

interface CreateArrayFunc {
    <T>(length: number, value: T): Array<T>;
}

let createArray: CreateArrayFunc;
createArray = function<T>(length: number, value: T): Array<T> {
    let result: T[] = [];
    for (let i = 0; i < length; i++) {
        result[i] = value;
    }
    return result;
}

createArray<string>(3, 'x'); // ['x', 'x', 'x']

评价:泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

声明合并

function foo(): number;
function foo(): string;
function foo(): number|string{
    return '1'+2
}

评价:如果定义了两个相同名字的函数、接口或类,那么它们会合并成一个类型。

拓展:变量never的适用范围

switch (letter) {
    case Letter.A:
        // ...
        break;
    case Letter.B:
        // ...
        break;
    case Letter.C:
        // ...
        break;
    default:
        const check: never = customType;
         
        // ...
        break;
}

评价:默认情况下应该不会进入default,错误进入时需要有never来迫使编译器进行报错。