分享一篇关于TypeScript基础语法总结

788a7f557284e08e5b159aacbe3d8a1e.jpeg

来源 | https://www.cnblogs.com/yinpengfei/p/17016910.html

一、部分关键字总结说明

1. extends

(1)在 JS 中,担当类的继承重担

 
  
App extends Component

(2)在 TS 类型中,当泛型约束

 
  
type ToUpper<S extends string> = xxx

(3)在 TS 类型中,条件判断的关键词

 
  
type ReturnType<T> = T extends () => infer R ? R : never'`

2. in

遍历,用于取联合类型的值,主要用于数组和对象的构造。不要用于 interface,否则会出错。

 
  
type Name = 'Tom' | 'John' | 'Sim'


type NameObj = {
  [T in Name]: string
}


/**
type NameObj = {
  Tom: string;
  John: string;
  Sim: string;
}
 */

3. keyof

获取类、对象、接口的所有属性名组成的联合类型。

 
  
type MyPerson = {
  name: string;
  age: number;
  hobbies: string[]
}


type ToReadonly<Obj> = {
  readonly [Key in keyof Obj]: Obj[Key]
}


type res = ToReadonly<MyPerson>
/**
type res = {
  readonly name: string;
  readonly age: number;
  readonly hobbies: string[];
}
 */

4. infer

泛型与条件与类型推断变量。表示在 extends 条件语句中以占位符出现的用来修饰数据类型的关键字,被修饰的数据类型等用到的时候才能被推断出来
作用:获取参数,返回值,泛型 的类型
出现位置:参数、返回值、类型的泛型具体化类型上

 
  
type NameType<T> = T extends (param: infer P) => any ? P : T

5. 联合:|

类似于 js 里的或运算符,但作为类型,代表类型可以是几个类型之一

 
  
type Name = 'Tom' | 'John' | 'Sim'

6. 交叉:&

类似于 js 里的与运算符,但作为类型,代表对当前几个类型的合并处理

 
  
type Name1 = 'Tom' | 'John' | 'Sim'
type Name2 = 'Sim' | 'Aim'


type ResName = Name1 & Name2 // type ResName = "Sim"

二、条件语句 三元表达式

 
  
type AA = 1 extends number ? 1 : never // 1
type IsRed = 'blue' extends 'red' ? true : false // false

三、声明文件

 
  
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
export 导出变量
export default ES6默认导出
export namespace 导出(含有子属性的)对象
export = commonjs 导出模块
export as namespace UMD库声明全局变量
declare global 扩展变量
declare module 扩展模块
/// <reference /> 三斜线指令

四、基础类型

string, number, boolean, null, undefined, any, never, enum(枚举), array(数组), tuple(元组), object, void

✨ never类型是所有类型的子类型

✨ undefined 在 tsconfig strictNullChecks 为 true 的情况下是 void 和 any 类型子类型,为 false 的情况下则除 never 的子类型

1. Enum

枚举类型用于取值被限定在一定范围内的场景

 
  
enum Days {
  Mon = 1,
  Tue, // 2
  Wed, // 3
  Thu, // 4
  Fri, // 5
  Sat, // 6
  Sun, // 7
}
let day = [Days.Sun, Days.Mon, Days.Fri] // day = [7, 1, 5]

2. Tuple

元组是个数有限、类型固定的数组类型

 
  
let tom1: readonly [string, number] = ['Tom', 25]
2.1 合并两个元组
 
  
type Concat<T extends any[], U extends any[]> = [...T, ...U]
type Res = Concat<[1], [2, 3]> // [1, 2, 3]
2.2 元组的遍历:递归方式,对象类型遍历方式

两种处理方式都能遍历到每个元素,并对每个元素做一些判断和处理。除了在会增加元素数量的情况下,必须使用递归的模式,其它情况可任选

(1)用递归思想解决元组拍平问题

 
  
type Flatten<T extends any[]> = T extends [infer First, ...infer Rest]
  ? (First extends any[]
    ? [...Flatten<First>, ...Flatten<Rest>]
    : [First, ...Flatten<Rest>])
  : []


type Res = Flatten<[1, [[2]]]> // [1,2]

(2) 希望 [1, () => number, string] 能够被处理成 [1, number, string]

 
  
type GetType<T extends any[]> = {
  [K in keyof T]: T[K] extends () => infer R ? R : T[K]
}


type Res = GetType<[1, () => number, string]> // [1, number, string]
2.3 元组与索引与联合类型
 
  
type tupleStr = ['a', 'b', 'c']


type AAA = tupleStr[0]; // 'a'
type BBB = tupleStr[1]; // 'b'
// 因为 number 代表了可能是 0 也可能是 1 或者 2,所以这些可能性组成的集合就是联合类型
type UnionStr = tupleStr[number]; // 'a' | 'b' | 'c' 变成了联合类型

3. 字符串字面量类型

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

3.1 类型别名与字符串字面量类型都是使用 type 进行定义#
 
  
type EventNames = 'click' | 'scroll' | 'mousemove'
function handleEvent (ele: Element, event: EventNames) {
  // do something
}
3.2 字符串操作:字符串类型推导与解构#

(1)推导类型中油字符串字面量的情况

 
  
// 实现一个将字符串类型中 _ 去除的功能,其可以为:
type DelUnderline<T extends string> = T extends `${infer LeftWords}_${infer RightWords}`
  ? `${LeftWords}${RightWords}`
  : T
type HelloWorld = DelUnderline<'hello_world'> // helloworld(LeftWords 为 hello,RightWords 为 world)
type World = DelUnderline<'_world'> // world(LeftWords 为空字符串,RightWords 为 world)
type Hello = DelUnderline<'hello_'> // hello(LeftWords 为 hello,RightWords 为空字符串)

(2)推导类型中无字符串字面量的情况

 
  
// 实现 TS 类型的首字母大写的效果,其可以为:
type MyCapitalize<T extends string> = T extends `${infer First}${infer Rest}`
  ? `${Uppercase<First>}${Rest}`
  : T;
type A19_2 = MyCapitalize<'hello'>; // "Hello"(First 为 "h",Rest 为 "ello")
type B = MyCapitalize<'b'>; // "B" (First 为 "h",Rest 为空字符串)
type C = MyCapitaliz
e<''>; // 当为空字符串时,会走到 false 的分支,返回空字符串

五、类型断言

 
  
// 值 as 类型 或 <类型>值
let ele = document.getElementById('id_1') as HTMLElement

六、类型守卫

  • 类型判断:typeof

  • 属性或者方法判断:in

  • 实例判断:instanceof

  • 字面量相等判断:==, =

    , !=, !

七、联合类型 and 类型别名

1. 联合类型

表示取值可以为多种类型中的一种

 
  
let username: string | number = 'yyy'

当ts不确定一个联合类型的变量到底是哪个类型的时候,我们只能“访问此联合类型所有类型里共有的属性或方法”

 
  
user1.toString()

联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型

 
  
user1 = 20 // 推断成number
1.1 联合类型与泛型推导
 
  
// 例子中并不是将 'a' | 'b' | 'c' 一次性判断的,而是一个一个走的判断
type Foo<T> = T extends 'a' | 'b' ? `${T}1` : T
type Bar = Foo<'a' | 'b' | 'c'> // "a1" | "b1" | "c"

2. 类型别名

类型别名: type 既可以表示基础类型,也可以表示对象类型

 
  
type Name = string | number
let name1: Name = 123

八、函数

1. 函数的类型

 
  
function buildName(firstName: string, lastName?: string, other:string = 'default'):string {
  if (lastName) {
    return firstName + ' ' + lastName + other
  } else {
    return firstName + other
  }
}

2. 用接口定义函数的形状

 
  
interface SearchFunc {
  (source: string, subString: string): boolean
}
let mySearch: SearchFunc
mySearch = function (source: string, subString: string) {
  return source.search(subString) !== -1
}

剩余参数 "...rest", 可选参数 "?", 默认参数 "="

 
  
function push(array: any[], name = 'yyy', age?: number, ...items: any[]) {
  items.forEach(item => {
    array.push(item)
  })
}

九、数组

 
  
let arr1: number[] = [1,2,3,4]
let arr2: Array<string> = ['1', '2']
let arr3: any[] = [1, '2', { k: 'v' }, [0]]

十、对象

  • ECMAScript 标准内置对象:Boolean、Error、Date、RegExp等

  • DOM 和 Bom:Document、HTMLElement、Event、NodeList等

十一、接口

 
  
interface Person4 {
  // 只读属性
  readonly id: number
  name: string
  age: number
  // 可选属性
  sex?: string
  // 任意属性取string类型的值
  // 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
  [x:string]: any
}


let tom: Person4 = {
  id: 1,
  name: 'Tom',
  age: 20
}

十二、类

1. 基础用法

 
  
class Animal {
  public name:string;
  private readonly age:number;
  public constructor(name:string, age: number) {
    this.name = name
    this.age = age
  }
  sayHi ():string {
    return `My name is ${this.name}, age is ${this.age} years old..`
  }
}
class Cat extends Animal {
  constructor(name, age) {
    super(name, age)
  }
  sayHi(): string {
    return super.sayHi()
  }
}

2. 类与接口

2.1 类实现接口
 
  
interface Alarm {
  alert():void
}
interface Light {
  lightOn():void
  lightOff():void
}


class Car implements Alarm, Light {
  alert(): void {
    console.log('car alert')
  }
  lightOn(): void {
    console.log('car lightOn')
  }
  lightOff(): void {
    console.log('car lightOff')
  }
}
2.2 接口继承接口
 
  
// LightableAlarm 继承了 Alarm,除了拥有 alert 方法之外,还拥有两个新方法 lightOn 和 lightOff
interface Alarm {
  alert():void
}


interface LightableAlarm extends Alarm {
  lightOn():void
  lightOff():void
}
2.3 接口继承类

在接口继承类的时候,也只会继承它的实例属性和实例方法

 
  
class Point {
  x: number
  y: number
  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
  fn () {
    console.log('fn...')
  }
}


interface Point3d extends Point {
  z: number
}
let point3d: Point3d = {
  x: 1,
  y: 2,
  z: 3,
  fn() {
    console.log('fn~', )
  },
}

十三、泛型

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

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

1. 泛型接口

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

2. 泛型类 泛型参数带默认类型

 
  
class GenericNumber<T = string> {
  zeroValue: T;
  add: (x:T, y:T) => T
}
let myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 1
myGenericNumber.add = (x, y) => x + y

3. 泛型约束

对输入参数进行校验,泛型中通过 extends 关键字实现

 
  
class Per {
  name: string;
}
function getName(user) {
  if (!(user instanceof Per)) {
    throw new Error(`${user} is not instanceof "Person"`);
  }
  return user.name;
}
type GetName<U extends Person> = U['name']

4. 泛型与条件判断

 
  
type IsBoolean<T> = T extends boolean ? true : false;
type AA = IsBoolean<true>; // true
type BB = IsBoolean<1>; // false

5. 泛型与条件与类型推断变量 infer

 
  
type ReturnType1<T> = T extends ((...args: any) => infer R) ? R : never;
type GetSum = (a: number, b: number) => number;
type A1 = ReturnType<GetSum> // number

6. ts内置泛型工具

 
  
// 1> Pick 挑选出指定属性,生成新对象类型
type UserInfo = Pick<Person, 'name' | 'age'>; // 挑选出 { name: string; age: number }


// 2> Omit 排除指定的属性,生成新的对象类型
type UserInfo2 = Omit<Person, 'id'>; // 排除 id,生成  { name: string; age: number }


// 3> Partial 将对象所有属性变为可选
type PartialPerson = Partial<Person>; // { name?: string; age?: number; id?: number }


// 4> Readonly 将对象所有属性变为只读
type ReadonlyPerson = Readonly<Person>; // { readonly name: string; readonly age: number; readonly id: number }


// 5> Record 生成对象类型,例如
type PersonMap = Record<number, Person>; // { [index: number]: Person }


// 6> Exclude 排除一些联合类型
type UserInfoKeys = Exclude<keyof Person, 'id'>; // 'name' | 'age'

十四、声明合并

1. 函数的合并

 
  
function reverse(x:number):number
function reverse(x:string):string
function reverse(x: number | string): number | string {
  if (typeof x === 'number') {
    return Number(x.toString().split('').reverse().join(''));
  } else if (typeof x === 'string') {
    return x.split('').reverse().join('')
  }
  return 0
}

2. 接口的合并

 
  
interface Alarm2 {
  price: number
  alert(s: string): string
}
interface Alarm2 {
  weight: number
  alert(s: string, n: number): string
}


// 想当于
interface Alarm2 {
  price: number
  weight: number
  // 接口中方法的合并,与函数的合并一样
  alert(s: string): string
  alert(s: string, n: number): string;
}

类的合并 类的合并与接口的合并规则一致

十五、其他

 
  
// 从 js 值转为 ts 值
const jack1 = {
  name: 'jack',
  age: 18
}


// 从 JS 中获取 TS 并赋值
type Person20 = typeof jack1; // 此时 Person 为 { name: string; age: number }


// 使用到 as const 语法,让其尽可能精准的推测
const jack2 = {
  name: 'jack',
  age: 18


} as const; // 会被推导为:{ readonly name: "jack"; readonly age: 18; }
const arr = [1, 2] as const;  // 会被推导为:readonly [1, 2];

45f0aa42003edc07a7df5a7ce924726d.png

以上就是今天的全部内容,希望对你有所帮助。

学习更多技能

请点击下方公众号

3617b544c4a36a651f68ca85131cc10a.gif

猜你喜欢

转载自blog.csdn.net/Ed7zgeE9X/article/details/134453355