TypeScript基础学习笔记

TypeScript基础

一、TypeScript是什么?

TypeScript 作为 JavaScript 语言的超集,它为 JavaScript 添加了可选择的类型标注,大大增强了代码的可读性和可维护性。同时,它提供最新和不断发展的 JavaScript 特性,能让我们建立更健壮的组件。

二、TypeScript三大特点:

  • 始于JavaScript,归于JavaScript

TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 3(或更高版本)的JavaScript 引擎中。

  • 强大的工具构建大型应用程序

类型允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。

类型是可选的,类型推断让一些类型的注释使你的代码的静态验证有很大的不同。

类型让你定义软件组件之间的接口和洞察现有 JavaScript 库的行为。

  • 先进的 JavaScript

TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性,比如异步功能和 Decorators,以帮助建立健壮的组件。

这些特性为高可信应用程序开发时是可用的,但是会被编译成简洁的 ECMAScript3(或更新版本)的JavaScript。

三、安装 TypeScript

命令行运行如下命令,全局安装 TypeScript:

npm install -g typescript

安装完成后,在控制台运行如下命令,检查安装是否成功:

tsc -V  // Version 4.6.3

四、基础类型

TypeScript 支持与 JavaScript 几乎相同的数据类型,此外还提供了实用的枚举类型。

布尔值:boolean

最基本的数据类型就是简单的 true/false 值。

const dialogvisible: boolean = false

数字:number

和 JavaScript 一样,TypeScript 里的所有数字都是浮点数。 除了支持十进制和十六进制字面量,TypeScript 还支持 ES6中引入的二进制和八进制字面量。

const decLiteral: number = 20
const hexLiteral: number = 0x14
const binaryLiteral: number = 0b10100
const octalLiteral: number = 0o24

大整数字:bigint

bigint 类型包含所有的大整数。bigint 与 number 类型不兼容。

const x:bigint = 123n;
const y:bigint = 0xffffn;

const x:bigint = 123; // 报错
const y:bigint = 3.14; // 报错

symbol

Symbol 是 ES2015 新引入的一种原始类型的值。它类似于字符串,但是每一个 Symbol 值都是独一无二的,与其他任何值都不相等。

Symbol 值通过Symbol()函数生成。在 TypeScript 里面,Symbol 的类型使用symbol表示。

let x:symbol = Symbol();
let y:symbol = Symbol();

x === y // false

字符串:string

JavaScript 程序的另一项基本操作是处理网页或服务器端的文本数据。和 JavaScript 一样,可以使用双引号(")或单引号(')表示字符串。也可以使用ES6的模板字符串。

const title: string = '学习TypeScript'
const course: string = `这门课程的课题是${title}`

数组:type[] / Array<type>

有两种方式可以定义数组:

  1. 在元素类型后面接上 [],表示由此类型元素组成的一个数组。
  2. 第二种方式是使用数组泛型。
const todoList: string[] = ['学习TypeScript', '使用TypeScript']
const progress: Array<number> = [100, 50]

元组Tuple:[type1, type2, …]

元组类型表示一个已知元素数量和类型的数组,各元素的类型不必相同。

const product: [string, number] = ['鼠标', 55]

当访问一个已知索引的元素,会得到正确的类型:

console.log(product[0].substr(1)) // OK
console.log(product[1].substr(1)) // Error, 'number' 不存在 'substr' 方法

当访问一个越界的元素,会使用联合类型替代:

注意:自从 TyeScript 3.1 版本之后,访问越界元素会报错,所以不能再使用该特性。

product[3] = '达尔优' // OK, 字符串可以赋值给(string | number)类型 before TyeScript v3.1
product[3] = '雷蛇' // Error, 长度为 "2" 的元组类型 "[string, number]" 在索引 "3" 处没有元素 after TyeScript v3.1

枚举:enum

enum 是一种用于定义命名常量集合的数据类型,是对 JavaScript 标准数据类型的一个补充。 像 C# 等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。

enum Info {
    name, 
    age, 
    gender
}

const studentName: Info = Info.name
console.log(studentName) // 0

默认情况下,从 0 开始为元素编号。 你也可以手动的指定成员的数值。

如果枚举属性没有赋值,那么就会获取其编号作为值。

enum Info {
    name = 2, 
    age, // 默认编号为3
    gender // 默认编号为4
}

const studentName: Info = Info.name
console.log(studentName) // 2
const studentAge: Info = Info.age
console.log(studentAge) // 3

如果枚举成员其中一个有赋值,则其他也必须赋值,否则会报错。

enum Info {
    name = 'Peter', 
    age, // Error 枚举成员必须具有初始化表达式。
    gender
}

枚举类型也可以根据枚举的值(编号)反推枚举成员名字:

enum Info {
    name, 
    age, 
    gender
}

const studentName: string = Info[0]
console.log(studentName) // 'name'

枚举类型转换成js的object:

enum Gender  {
  M = '男',
  F = '女',
  UNKNOW = '未知'
}

const gender1 = Object.fromEntries(Object.entries(Gender));
console.log(gender1); // {M: '男', F: '女', UNKNOW: '未知'}

const gender2 = { ...Gender }
console.log(gender2); // {M: '男', F: '女', UNKNOW: '未知'}

import { Gender } from '@/enum'
console.log(Gender); // {M: '男', F: '女', UNKNOW: '未知'}

const枚举:在编译时被删除并内联到引用它们的地方。这可以提高性能和减少生成的代码大小

const enum Direction {
  Up,
  Down,
  Left,
  Right
}
 
console.log(Direction.Up); // 直接输出0,没有额外的代码生成

任意值:any

当需要给不清楚类型的变量指定一个类型,如用户输入内容或第三方代码库,可以使用 any类型来标记这些变量。类型检查器会跳过对any类型的检查。

let anyName: any = 'any'
anyName = 2023
anyName = true

// 也可以使用any指定包含不同类型数据的数组类型
let anyList: any[] = [2023, 'typescript']
anyList[2] = false

空值:void

void表示没有任何类型, 当一个函数没有返回值时,通常将其返回值类型设置为 void

function setClass(): void {
    console.log('set class')
}

声明一个 void 类型的变量,只能为它赋予 undefined

const isVoid: void = undefined

null 和 undefined

null类型的变量只能赋值为nullundefined类型的变量也只能赋值为undefined,这两个类型更多的用于联合类型。

let isNull: null = null
let isUndefined: undefined = undefined

never

never表示的是那些永不存在的值的类型,如报错函数的返回值,或者无限循环函数的返回值。

function thorwError(msg: string): never {
  throw new Error(`Error: ${msg}`)
}

function infiniteLoop(): never{
    for(;;){}
}

由于TypeScript没有if else语法,进行类型运算都是使用三目运算符,never往往用作三目运算的逃出条件

never类型实际应用

type Method = 'POST' | 'GET'

// 根据Method类型的定义,else分支永远不会到达,else里面的method的类型就是never
function request(method: Method, url: string): string{
    if(method === 'POST'){
		return method
    }else if(method === 'GET'){
	    return method
    }else {
        const m: never = method
        return m
    }
}

// 当method类型修改了,比如增加'PUT'
type Method = 'POST' | 'GET' | 'PUT'

// else分支就有可能到达,并且类型就是'PUT',编译就会报错
// Error: 不能将类型“string”分配给类型“never”。
// 设置一个函数参数,可以是任何类型,但不能是数字类型
// 就可以使用泛型去排除number类型,如果是number则设置为never
function excludeNum<T>(x: T extends number ? never : T) {
    console.log(x)
}

excludeNum(true)
excludeNum('string')
excludeNum(2023)

// 更通用的做法,排除任意类型
type BanType<T, E> = T extends E ? never : T
function excludeNum<T>(x:  BanType<T, string>) {
    console.log(x)
}

对象:object

object 表示非原始类型,也就是除 numberstringbooleansymbolnullundefined 之外的类型,实际开发中更多会使用interface,Record来定义对象的类型。

let obj: object
obj = {} // Ok
obj = [] // Ok
obj = null //Error 不能将类型“null”分配给类型“object”。
obj = 'hello world' //Error 不能将类型“sting”分配给类型“object”。
obj = 2023 //Error 不能将类型“number”分配给类型“object”。

值类型

TypeScript 规定,单个值也是一种类型,称为“值类型”。

let x:'hello'; // hello类型

x = 'hello'; // 正确
x = 'world'; // 报错

联合类型:union types

联合类型指的是多个类型组成的一个新类型,使用符号|表示。联合类型A|B表示,任何一个类型只要属于AB,就属于联合类型A|B

let x: string|number;

x = 123; // 正确
x = 'abc'; // 正确

交叉类型:intersection types

交叉类型指的多个类型组成的一个新类型,使用符号&表示。

交叉类型A&B表示,任何一个类型必须同时属于AB,才属于交叉类型A&B,即交叉类型同时满足AB的特征。

let x: number & string; // never

交叉类型的主要用途是表示对象的合成,或者用来为对象类型添加新属性。

let obj:
  { foo: string } &
  { bar: string };

obj = {
  foo: 'hello',
  bar: 'world'
};

五、类型断言(Type Assertion)

类型断言就是可以告诉TypeScript编译器已经人为确认了某个值的具体类型。

有两种语法实现:

as 类型

let year:unknown = 2023
let len = (year as string).length

<类型>let someValue: any = 'this is a string'
let strLength: number = (<string>someValue).length

在 tsx 语法(React 的 jsx 语法的 ts 版)中必须使用前者,即 值 as 类型

形如 <Foo> 的语法在 tsx 中表示的是一个 ReactNode,在 ts 中除了表示类型断言之外,也可能是表示一个泛型

故建议使用类型断言时,统一使用 值 as 类型 这样的语法。

六、接口(Interface)

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

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

TypeScript 的核心原则之一是对值所具有的结构进行类型检查。它有时被称做“鸭式辨型法”或“结构性子类型化”。 在 TypeScript 里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

interface Person {
    readonly name: string // 只读属性,不能重新赋值
    age: number
    isMale?: boolean // 可选属性,可以没有
    [propName: string]: string | number | boolean | undefined // 任意属性,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
}

const jack: Person = {
    name:'jack',
    age: 18,
    isMale: true, // 不加不会报错
    weight: '100kg' 
}

jack.name = 'peter' // Error 无法为“name”赋值,因为它是只读属性。

函数类型

函数也是对象,于是接口也能够用来描述函数类型。

interface AddFunc {
    (param1:number, param2:number): number
}

const add: AddFunc = (a,b) => a + b

类类型

接口用于描述类(class)的形状,使用implements关键字

interface PersonInterface {
    name: string
    age: number
}

class Person implements PersonInterface {
    name: string
    age: number
    constructor(){
        console.log(this.name, this.age)
    }
}

接口继承接口

接口与接口之间可以是继承关系,使用extends关键字。一个接口可以继承一个或多个接口, 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。

interface Person {
    name: string
    age: number
}

interface Student {
    class: string
}

interface Boy extends Person, Student {
    gender: string
}

const boy: Boy = {
    name: 'Jack',
    age: 12,
    gender: 'male',
    class: '六年二班'
}

接口继承类

当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的 privateprotected 成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。

class Control {
  private state: any
}

interface SelectableControl extends Control {
  select(): void
}

class Button extends Control implements SelectableControl {
  select() { }
}

class TextBox extends Control {
  select() { }
}

// Error:“ImageC”类型缺少“state”属性。
class ImageC implements SelectableControl {
  select() { }
}

七、泛型(Generic)

软件工程中,我们不仅要创建定义良好且一致的 API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像 C# 和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

function something1(arg: any): any {
    return arg
  }

const hello = something1('hello') // hello: any


function something2<T>(arg: T): T {
    return arg
  }

const earth = something2<string>('earth') // earth: string
const world = something2('world') // world: 'world'

// 还可以使用带有调用签名的对象字面量来定义泛型函数:
let thing: {<T>(arg: T): T} = something2

泛型接口

把上例改写成泛型接口,可以把上例里的对象字面量拿出来做为一个接口:

function something<T>(arg: T): T {
    return arg
}

interface GenericInterface  {
    <T>(arg: T): T
}

let somethingElse: GenericInterface = something

也可以把泛型参数当作整个接口的一个参数。 这样我们就能清楚的知道使用的具体是哪个泛型类型,这样接口里的其它成员也能知道这个参数的类型了。

function something<T>(arg: T): T {
    return arg
}

interface GenericInterface<T>  {
    (arg: T): T
}

let somethingElse: GenericInterface<string> = something

泛型类

泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。

class GenericNumber<T> {
  zeroValue: T
  add: (x: T, y: T) => T
}

let myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 0
myGenericNumber.add = function(x, y) {
  return x + y 
}

泛型约束

有时候想操作某类型的一组值,并且我们知道这组值具有什么样的属性。如下例,访问 arglength 属性,但是编译器并不能证明每种类型都有 length 属性,所以就报错了。

function getLength<T>(arg: T): T {
  console.log(arg.length) // error: 类型“T”上不存在属性“length”
  return arg
}

我们可以定义一个接口来描述约束条件,创建一个包含 .length 属性的接口,使用这个接口和 extends 关键字来实现约束:

interface Lengthwise {
  length: number
}

function getLength<T extends Lengthwise>(arg: T): T {
  console.log(arg.length) // OK
  return arg
}

八、类型运算符(Operator)

TypeScript 提供强大的类型运算能力,可以使用各种类型运算符,对已有的类型进行计算,得到新类型。

type命令

type命令用来定义一个类型的别名。

type Age = number;

let age:Age = 55;

使用type命令定义的别名别名支持使用表达式,也可以在定义一个别名时,使用另一个别名,即别名允许嵌套。

type World = "world";
type Greeting = `hello ${World}`; // hello world

typeof 运算符

TypeScript 将JavaScript的typeof运算符移植到了类型运算,它的操作数依然是一个值,但是返回的不是字符串,而是该值的 TypeScript 类型。

const a = { x: 0 };

type T0 = typeof a;   // { x: number }
type T1 = typeof a.x; // number

由于编译时不会进行 JavaScript 的值运算,所以TypeScript 规定,typeof 的参数只能是标识符,不能是需要运算的表达式。

type T = typeof Date(); // 报错

另外,typeof命令的参数不能是类型。

type Age = number;
type MyAge = typeof Age; // 报错

keyof 运算符

keyof 是一个单目运算符,接受一个对象类型作为参数,返回该对象的所有键名组成的联合类型。

type MyObj = {
    foo: number,
    bar: string,
  };
  
type Keys = keyof MyObj; // 'foo'|'bar'

keyof 运算符往往用于精确表达对象的属性类型。

// normal
function prop(
    obj: { [p: string]: any },
    key: string
): any {
    return obj[key];
}

let obj = prop({ a: 'a', b: 'b' }, 'a')

// better
function prop2<Obj, K extends keyof Obj>(
    obj: Obj, key: K
): Obj[K] {
    return obj[key];
}

let obj2 = prop2({ a: 'a', b: 'b' }, 'b')

使用keyof typeof 可获取枚举的所有键的联合类型。

enum Gender  {
  M = '男',
  F = '女',
  UNKNOW = '未知'
}

type gender = keyof typeof Gender // type gender = "M" | "F" | "UNKNOW"

in 运算符

TypeScript 语言的类型运算中,in运算符用来取出(遍历)联合类型的每一个成员类型。

type U = 'a'|'b'|'c';

type Foo = {
  [Prop in U]: number;
};

// 等同于
type Foo = {
  a: number,
  b: number,
  c: number
};

[] 方括号运算符

方括号运算符([])用于取出对象的键值类型,比如T[K]会返回对象T的属性K的类型。

type Person = {
  age: number;
  name: string;
  alive: boolean;
};

// Age 的类型是 number
type Age = Person['age'];

extends…?: 条件运算符

TypeScript 提供类似 JavaScript 的?:运算符这样的三元运算符,但多出了一个extends关键字。

条件运算符extends...?:可以根据当前类型是否符合某种条件,返回不同的类型。

// true
type T = 1 extends number ? true : false;

// 可嵌套使用,进行多重判断,返回一个字符串的值类型,对应当前类型
type LiteralTypeName<T> =
  T extends undefined ? "undefined" :
  T extends null ? "null" :
  T extends boolean ? "boolean" :
  T extends number ? "number" :
  T extends bigint ? "bigint" :
  T extends string ? "string" :
  never;

// "string" | "number" | "boolean"
type Result2 = LiteralTypeName<true | 1 | 'a'>;

infer 关键字

infer关键字用来定义泛型里面推断出来的类型参数,而不是外部传入的类型参数。

type Flatten<Type> =
  Type extends Array<infer Item> ? Item : Type;

// string
type Str = Flatten<string[]>;

// number
type Num = Flatten<number>;

使用infer关键字提取对象指定属性

type MyType<T> =
  T extends {
    a: infer M,
    b: infer N
  } ? [M, N] : never;

type T = MyType<{ a: string; b: number }>;
// [string, number]

通过正则匹配提取类型参数

type Str = 'foo-bar';

type Bar = Str extends `foo-${infer rest}` ? rest : never // 'bar'

is 运算符

函数返回布尔值的时候,可以使用is运算符,限定返回值与参数之间的关系

type A = { a: string };
type B = { b: string };

function isTypeA(x: A | B): x is A {
    if ('a' in x) return true;
    return false;
}

// C: boolean
let C = isTypeA({ b: 'b' })

is运算符还可以用于类型保护

type Cat = { name: 'kitty', meow: Function }
type Dog = { name: 'bobo',wool: Function }

function isCat(a: any): a is Cat {
    return a.name === 'kitty';
}

let x: Cat | Dog;

if (isCat(x)) {
    x.meow(); // 正确,因为 x 肯定是 Cat 类型
}

模板字符串

TypeScript 允许使用模板字符串,构建类型。模板字符串的最大特点,就是内部可以引用其他类型。

type World = "world";

// "hello world"
type Greeting = `hello ${World}`;

注意:模板字符串可以引用的类型一共6种,分别是 string、number、bigint、boolean、null、undefined。引用这6种以外的类型会报错。

satisfies 运算符

satisfies运算符用来检测某个值是否符合指定类型。有时候,不方便将某个值指定为某种类型,但是希望这个值符合类型条件,这时候就可以用satisfies运算符对其进行检测。

type Colors = "red" | "green" | "blue";
type RGB = [number, number, number];

// normal
const palette: Record<Colors, string|RGB> = {
  red: [255, 0, 0],
  green: "#00ff00",
  bleu: [0, 0, 255] // 报错
};

const greenComponent = palette.green.substring(1, 6); // 报错

// better
const palette = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255] // 报错
  } satisfies Record<Colors, string|RGB>;
  
const greenComponent = palette.green.substring(1); // 不报错

九、Typescript内置类型工具(Utility)

在使用TypeScript的过程中,我们是面向类型编程的。为了满足不同的工作场景,我们需要对已知的类型进行改造。为了方便 TypeScript 用户,TypeScript 开发团队为我们提供了很多有用的内置实用类型。有了这些实用类型,我们可以很方便地转换类型、提取类型、排除类型,或者获取函数的参数类型或返回值类型。

Partial< Type>

构造一个 Type 的所有属性都设置为可选的类型。

/**
 * Make all properties in T optional. 
 */
type Partial<T> = {
    [P in keyof T]?: T[P];
};

type Person = {
    name: string,
    age: number,
    hobbies: string[]
}

// normal
type Boy = {
    name?: string,
    age?: number,
    hobbies?: string[]
}

// better
type Girl = Partial<Person>

Required< Type>

构造一个类型,该类型由设置为必需的 Type 的所有属性组成,与 Partial 相反。

/**
 * Make all properties in T required.
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};

type Person = {
    name?: string,
    age?: number,
    hobbies?: string[]
}

type Boy = {
    name: string,
    age: number,
    hobbies: string[]
}

type Girl = Required<Person>

Readonly< Type>

构造一个 Type 的所有属性都设置为只读的类型,这意味着不能重新分配构造类型的属性。

/**
 * Make all properties in T readonly.
 */
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

type Person = {
    name?: string,
    age?: number,
    hobbies?: string[]
}

type Boy = Readonly<Person>

ReadonlyArray< Type>

生成一个只读数组类型,类型参数Type表示数组成员的类型。

interface ReadonlyArray<T> {
    /**
     * Gets the length of the array. This is a number one higher than the highest element defined in an array.
     */
    readonly length: number;
    /**
     * Returns a string representation of an array.
     */
    toString(): string;
    /**
     * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods.
     */
    toLocaleString(): string;
    /**
     * Combines two or more arrays.
     * @param items Additional items to add to the end of array1.
     */
    concat(...items: ConcatArray<T>[]): T[];
    /**
     * Combines two or more arrays.
     * @param items Additional items to add to the end of array1.
     */
    concat(...items: (T | ConcatArray<T>)[]): T[];
    /**
     * Adds all the elements of an array separated by the specified separator string.
     * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
     */
    join(separator?: string): string;
    /**
     * Returns a section of an array.
     * @param start The beginning of the specified portion of the array.
     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.
     */
    slice(start?: number, end?: number): T[];
    /**
     * Returns the index of the first occurrence of a value in an array.
     * @param searchElement The value to locate in the array.
     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
     */
    indexOf(searchElement: T, fromIndex?: number): number;
    /**
     * Returns the index of the last occurrence of a specified value in an array.
     * @param searchElement The value to locate in the array.
     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
     */
    lastIndexOf(searchElement: T, fromIndex?: number): number;
    /**
     * Determines whether all the members of an array satisfy the specified test.
     * @param predicate A function that accepts up to three arguments. The every method calls
     * the predicate function for each element in the array until the predicate returns a value
     * which is coercible to the Boolean value false, or until the end of the array.
     * @param thisArg An object to which the this keyword can refer in the predicate function.
     * If thisArg is omitted, undefined is used as the this value.
     */
    every<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): this is readonly S[];
    /**
     * Determines whether all the members of an array satisfy the specified test.
     * @param predicate A function that accepts up to three arguments. The every method calls
     * the predicate function for each element in the array until the predicate returns a value
     * which is coercible to the Boolean value false, or until the end of the array.
     * @param thisArg An object to which the this keyword can refer in the predicate function.
     * If thisArg is omitted, undefined is used as the this value.
     */
    every(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;
    /**
     * Determines whether the specified callback function returns true for any element of an array.
     * @param predicate A function that accepts up to three arguments. The some method calls
     * the predicate function for each element in the array until the predicate returns a value
     * which is coercible to the Boolean value true, or until the end of the array.
     * @param thisArg An object to which the this keyword can refer in the predicate function.
     * If thisArg is omitted, undefined is used as the this value.
     */
    some(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;
    /**
     * Performs the specified action for each element in an array.
     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
     */
    forEach(callbackfn: (value: T, index: number, array: readonly T[]) => void, thisArg?: any): void;
    /**
     * Calls a defined callback function on each element of an array, and returns an array that contains the results.
     * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
     * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
     */
    map<U>(callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any): U[];
    /**
     * Returns the elements of an array that meet the condition specified in a callback function.
     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.
     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.
     */
    filter<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[];
    /**
     * Returns the elements of an array that meet the condition specified in a callback function.
     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.
     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.
     */
    filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[];
    /**
     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;
    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;
    /**
     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;
    /**
     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;
    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;
    /**
     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;

    readonly [n: number]: T;
}

Record<Keys, Type>

构造一个对象类型,其属性键为 Keys,其属性值为 Type,该实用程序可用于将一种类型的属性映射到另一种类型。

/**
 * Construct a type with a set of properties K of type T.
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

type Person = {
    name: string,
    age: number,
    hobbies: string[]
}

type Names = 'Jack' | 'Tom'

type Boy = Record<Names, Person>

Exclude<UnionType, ExcludedMembers>

通过从 UnionType 中排除所有可分配给 ExcludedMembers 的联合成员来构造一个类型。

/**
 * Exclude from T those types that are assignable to U.
 */
type Exclude<T, U> = T extends U ? never : T;

type Person = string | number | {}

type Boy = Exclude<Person, string>

Extract<Type, Union>

通过从 Type 中提取可分配给 Union 的所有联合成员来构造一个类型。

/**
 * Extract from T those types that are assignable to U.
 */
type Extract<T, U> = T extends U ? T : never;

type Person = 'boy' | 'girl' | 'child'

type Boy = Extract<Person, string>
type Girl = Extract<Person, 'girl'>

Pick<Type, Keys>

通过从 Type 中选择一组属性键(字符串文字或字符串文字的并集)来构造一个类型。

/**
 * From T, pick a set of properties whose keys are in the union K.
 */
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

type Person = {
    name: string,
    age: number,
    hobbies: string[]
}

type Boy = Pick<Person, 'name' | 'age'>

Omit<Type, Keys>

通过从 Type 中选择所有属性然后删除键(字符串文字或字符串文字的并集)来构造一个类型。

/**
 * Construct a type with the properties of T except for those in type K. 
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

type Person = {
    name: string,
    age: number,
    hobbies: string[]
}

type Boy = Omit<Person, 'name' | 'age'>

NonNullable< Type>

通过从 Type 中排除 null 和 undefined 来构造一个类型。

/**
 * Exclude null and undefined from T.
 */
type NonNullable<T> = T extends null | undefined ? never : T;

type Person = string | { name: string, age: number } | null | undefined

type Boy = NonNullable<Person>

Parameters< Type>

根据函数类型 Type 的参数中使用的类型构造元组类型。

/**
 * Obtain the parameters of a function type in a tuple.
 */
type Parameters<T extends (...args: any) => any> = T extends 
  (...args: infer P) => any ? P : never;

function getUserInfo(name: string, age: number){
    return {
        name,
        age
    }
}

type params = Parameters<typeof getUserInfo>

ReturnType< Type>

构造一个由函数 Type 的返回类型组成的类型。

/**
 * Obtain the return type of a function type.
 */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

function getUserInfo(name: string, age: number){
    return  [name, age]
}

type params = ReturnType<typeof getUserInfo>

Uppercase< StringType>

将字符串文字类型转换为大写。

Lowercase< StringType>

将字符串文字类型转换为小写。

/**
 * Convert string literal type to uppercase
 */
type Uppercase<S extends string> = intrinsic;

/**
 * Convert string literal type to lowercase
 */
type Lowercase<S extends string> = intrinsic;

Capitalize< StringType>

将字符串文字类型的第一个字符转换为大写。

Uncapitalize< StringType>

将字符串文字类型的第一个字符转换为小写。

/**
 * Convert first character of string literal type to uppercase
 */
type Capitalize<S extends string> = intrinsic;

/**
 * Convert first character of string literal type to lowercase
 */
type Uncapitalize<S extends string> = intrinsic;

intrinsic关键字用于表示一些与 TypeScript 类型系统有关的内置特性,例如 “string”、“number”、“boolean” 等基本类型,以及 “Array”、“Object” 等通用类型。

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值