TypeScript 类型-数据类型进阶

44 阅读2分钟

此文为查缺补漏,并不是文档的翻译,大部分内容均为回顾。如果想从零学习,建议直接查看参考链接

由于本人之前是写 Swift,对于很多概念,如类型推断、类型断言、可选类型已有了解,并不会写这块。其他已有概念只会列出使用方法,并不会列举具体示例。

日常类型

见我写的另一篇文章 基础数据类型

联合类型

取若干个类型中的一种

const id = number | string | boolean | other...

类型别名

给类型取别名,使其更符合对应的语义

type User = { name: string, age: number }
type Student = User

type 和 interface 的区别

interface 定义接口(应该以行为为判断拆分依据),type 定义类型(以属性为拆分依据),但两者的使用极其接近,但也有区别,区别如下

  1. 添加新类型
interface Animal {
  name: string
}
interface Dog extends Animal {
  age: number
}

type Animal = {
  name: string
}
type Dog = {
  name: string
} & {
  age: string
}
  1. interface 可以同名,直接追回进原类型,type 不可以同名,会报错
interface A {
  name: string
}
interface A {
  age: number
}

Narrowing

判断对象中是否存在某个属性

interface Fish {
  swim: () => void
}

interface Bird {
  fly: () => void
}

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    return animal.swim()
  }
  animal.fly()
}

使用类型谓词

当我们封装判断类型时,即使判断成功后,编译器仍然会报错,这时就需要使用 is 来告诉编译器

function isFish(pet: Fish | Bird): pet is Fish {
  return 'swim' in pet
}

const pet: Fish | Bird =  { swim: noop, fly: noop }
if (isFish(pet)) {
  pet.swim()
}

函数类型

泛型

function longest<Type extends { length: number }>(a: Type, b: Type) {
  if (a.length >= b.length) {
    return a;
  } else {
    return b;
  }
}
const longerArray = longest([1, 2], [1, 2, 3]);
const longerString = longest("alice", "bob");

函数重载

function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
    if (d !== undefined && y !== undefined) {
        return new Date(y, mOrTimestamp, d);
    } else {
        return new Date(mOrTimestamp);
    }
}
const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
const d3 = makeDate(1, 3);

unknown

类似 any,但更安全

function f1(a: any) {
    a.b(); ✅
}

function f2(a: unknown) {
    a.b(); ❌
    // Object is of type 'unknown'.Object is of type 'unknown'.
}

never

绝不会存在任何返回值,哪怕是 undefined,一般用于 throw 或者死循环

Type Manipulation

泛型

泛型约束

见上面泛型

泛型参数约束

function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
    return obj[key];
}

Using Class Types in Generics

function create<Type>(c: { new (): Type }): Type {
    return new c();
}

keyof

将类型中的 key 取出来

type A = { name: string, age: number }
type B = typeof A //相当于 type B = 'name' | 'age'

typeof

function f() {
    return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
// 相当于
type P = { x: number; y: number; }

参考

www.typescriptlang.org/docs/handbo…