快速入门TypeScript

89 阅读5分钟

基本使用

基本类型的注解

很简单 variableName: TypeAnnotation 即可,例:

let num: number;
let str: string;
let bool: boolean;

数组类型

数组类型用 :TypeAnnotation[] 表示,例:

let boolArray: boolean[];

接口

能合并众多类型声明至一个类型声明

例:

interface Name {
  first: string;
  second: string;
}

let name: Name;
name = {
  first: 'John',
  second: 'Doe'
};

内联注释语法

与接口不同,但是也可以实现接口的功能,好处在于不用单独去定义一个接口,省去了取名的麻烦,适用于仅使用一次的接口

let name: {
  first: string;
  second: string;
};

name = {
  first: 'John',
  second: 'Doe'
};

特殊类型

  1. any ⇒ 关闭类型检查,可以使用任何类型
  2. null ⇒ 可赋值给任何类型的变量
  3. undefined ⇒  同null
  4. void ⇒ 表示函数无返回值

泛型

当无法确定入参时又想将返回值强制类型,可以考虑使用泛型,它将自动识别入参的类型并且将返回值的类型设置的与入参一样。例:

function reverse<T>(items: T[]): T[] {
  const toreturn = [];
  for (let i = items.length - 1; i >= 0; i--) {
    toreturn.push(items[i]);
  }
  return toreturn;
}

const sample = [1, 2, 3];
let reversed = reverse(sample);

console.log(reversed); // 3, 2, 1

// Safety
reversed[0] = '1'; // Error
reversed = ['1', '2']; // Error

reversed[0] = 1; // ok
reversed = [1, 2]; // ok

事实上,JavaScript 数组已经拥有了 reverse 的方法,TypeScript 也确实使用了泛型来定义其结构:

interface Array<T> {
  reverse(): T[];
}

这意味着,当你在数组上调用 .reverse 方法时,将会获得类型安全

联合类型(支持多类型)

联合类型它使用 | 作为标记,如 string | number

例:

let name: string[] | string

注意:当联合类型的子类型非基本类型时,联合类型读取时仅显示其共同的属性名,联合类型赋值时只能选择子类型之一

交叉类型

交叉类型它使用 & 作为标记,如 string & number

注意:当交叉类型的子类型非基本类型时,交叉类型读取时显示所有的属性名,交叉类型赋值时无法赋值属性名相同但是类型不同的属性(将会变为never类型)

元祖类型

在JS里原本并不支持元祖,通常只能用数组来表示元祖。

通常形式为::[typeofmember1, typeofmember2]

类型别名

类型别名可以理解为另外一种非对象的interface 的写法

用法:type SomeName = someValidTypeAnnotation

type StrOrNum = string | number;

// 使用
let sample: StrOrNum;
sample = 123;
sample = '123';

// 会检查类型
sample = true; // Error

声明文件

declare 用来声明已经存在的代码,一般声明都会放在独立的.d.ts中可以命名一个global.d.ts 文件用于存放声明

枚举类型

枚举类型实际是就是默认从0下标开始的对象

enum color {
    red,
    blue,
    yellow
}

Untitled转存失败,建议直接上传图片文件

改变原有的枚举的数字逻辑

默认情况下,第一个枚举值是 0,然后每个后续值依次递增 1:

enum Color {
  Red, // 0
  Green, // 1
  Blue // 2
}

但是,你可以通过特定的赋值来改变给任何枚举成员关联的数字,如下例子,我们从 3 开始依次递增:

enum Color {
  DarkRed = 3, // 3
  DarkGreen, // 4
  DarkBlue // 5
}

字符串枚举

这是最常用也是最好用的一种枚举用法,可以覆盖我们大多数的使用的情况

enum EvidenceTypeEnum {
    UNKNOWN = '',
    PASSPORT_VISA = 'passport_visa',
    PASSPORT = 'passport',
    SIGHTED_STUDENT_CARD = 'sighted_tertiary_edu_id',
    SIGHTED_KEYPASS_CARD = 'sighted_keypass_card',
    SIGHTED_PROOF_OF_AGE_CARD = 'sighted_proof_of_age_card'
}

函数

参数注解

最开始说的所有方法都可以使用,内联,接口等

function foo(**sampleParameter: { bar: number }**) {}

返回类型的注解

可以在函数参数列表之后使用与变量相同的样式来注解返回类型

interface Foo {
  foo: string;
}

// Return type annotated as `: Foo`
function foo(sample: Foo): Foo {
  return sample;
}

但是也不需要注解返回类型,编译器也会进行自动推断

但是添加可以帮助你错误提示!

function foo(sample: Foo) {
  return sample; // inferred return type 'Foo'
}

可选参数 | 参数默认值

function foo(bar: number, bas?: string): void {
  // ..
}

foo(123);
foo(123, 'hello');

function foo(bar: number, bas: string = 'hello') {
  console.log(bar, bas);
}

foo(123); // 123, hello
foo(123, 'world'); // 123, world

函数方法重载

方法重载是函数中一个很重要的概念,它可以通过传入参数的不同来使函数得到不同的效果

// 重载
function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);
// Actual implementation that is a true representation of all the cases the function body needs to handle
function padding(a: number, b?: number, c?: number, d?: number) {
  if (b === undefined && c === undefined && d === undefined) {
    b = c = d = a;
  } else if (c === undefined && d === undefined) {
    c = a;
    d = b;
  }
  return {
    top: a,
    right: b,
    bottom: c,
    left: d
  };
}

// 调用
padding(1); // Okay: all
padding(1, 1); // Okay: topAndBottom, leftAndRight
padding(1, 1, 1, 1); // Okay: top, right, bottom, left

padding(1, 1, 1); // Error: Not a part of the available overloads

这样也可以让调用者只能输入固定数量的入参,如果没有使用方法重载的情况下允许参入四个参数时,调用者可能会传入不合法的三个参数导致出现错误。

函数声明

在没有提供函数实现的情况下,有两种声明函数类型的方式:

// 函数重载只能用这种方式
type LongHandAllowsOverloadDeclarations = {
  (a: number): number;
  (a: string): string;
};

// 箭头函数声明方法(函数重载不能用哦~)
type ShortHand = (a: number) => number;

上面代码中的两个例子完全相同。但是,当你想使用函数重载时,只能用第一种方式:

类型断言

在编译时,类型断言技术可以来覆盖浏览器的推断(报错)

例如:

const foo = {};
foo.bar = 123; // Error: 'bar' 属性不存在于 ‘{}’
foo.bas = 'hello'; // Error: 'bas' 属性不存在于 '{}'

这里的代码发出了错误警告,因为 foo 的类型推断为 {},即没有属性的对象。因此,你不能在它的属性上添加 bar 或 bas,你可以通过类型断言来避免此问题:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';