• TS 基础


    TS基础

    TS环境

    安装ts : npm i -g typescript
    编译ts文件: tsc test.ts

    类型

    类型声明

    let a : number
    
    let b : string = '123'
    
    function func(c : boolean) : string {
      return c ? '123' : '321'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    类型介绍

    number、string、boolean
    字面量

    描述变量的值为类型的本身

    let d : 'A'  |  true  |  2
    d = 'A'
    d = true
    d = 2
    
    • 1
    • 2
    • 3
    • 4
    any
    let a : any
    
    • 1

    表示任意类型,一个变量设置类型为any后视为放弃TS类型检测,相当于JS

    let a
    
    • 1

    如果声明变量不指定类型,TS解析器会将该变量视为any

    let d : 'A' | true | 2
    let e : any
    d = e
    
    • 1
    • 2
    • 3

    当变量的类型为any时,赋值给任何类型的变量都不会报错

    unknown

    类型为unknown的变量,可以给自己赋值任何类型的值,但不能直接赋值给其他变量

    let d : 'A' | true | 2
    let e : unknown
    if(e === 'A'){
      d = e
    }
    
    let a : string
    let b : unknown
    if(typeof b === 'string'){
      a = b
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    void

    用来表示空,一般用在函数返回值,表示没有返回值

    function func() : void{
      return null
    }
    function func1() : void{
      return undefined
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    没有返回值的函数,默认分配void类型

    function warnUser() {
      console.log("This is my warning message");
    }
    
    • 1
    • 2
    • 3
    never

    表示变量某种不可能存在的情况

    const a = 123;
    if (a !== 123) {
        const b = a;    // b: never
    }
    
    • 1
    • 2
    • 3
    • 4

    表示函数永远不会返回结果,但是可用来做抛出错误的函数

    function func1() : never{
      throw new Error('错误')
    }
    
    function fun2(): never {
      return process.exit(1)
    }
    
    function fun3(): never {
      while (true) {
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    某些时候never可以用来检查代码是否严谨或者是否遗漏
    举例:

    type All = string  |  number
    function handle(val : All) {
      switch (typeof val) {
        case 'string':
        break;
        case 'number':
        break;
        default:
        const a :  never = val    
        break;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    object
    let a : object
    a = { }
    a = function () { }
    
    • 1
    • 2
    • 3
    let a:{name : string,age? : number,sex? : string}
    a = {name : '111',sex : '男'}
    
    • 1
    • 2
    let a : {name : string , [propName : string] : any}
    a = {name : '111',age : 12, true : 1, 1 : '123'}
    
    • 1
    • 2
    let d : (a : number, b : number) => number
    d = function (n1 : number,n2 : number):number {
      return 0
    }
    
    • 1
    • 2
    • 3
    • 4
    array

    数组

    let a : string[ ]
    a = [ 'a' , 'b' , 'c']
    
    let b : Array<number>
    b = [1, 2, 3]
    
    let c : (string | number | boolean)[ ];
    c = [1 , 1, 'a', true]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    tuple 元组

    长度、类型、顺序固定的数组

    let a: [string, number, boolean]
    a = ['1', 1, false]
    
    • 1
    • 2
    enum 枚举

    列举一些类型

    enum MyType {
      A = 1,
      B,
      C
    }
    
    let a : MyType
    a = MyType.A
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    enum MyType{
      A = 100,
      B = 99,
      C
    }
    console.log(MyType.A === MyType.C);//true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    类型断言

    let a : string
    let b : unknown
    a = b as string
    a = <string>b
    
    • 1
    • 2
    • 3
    • 4
    • 变量 as 类型
    • <类型>变量

    类型别名

    对于一些复杂的自定义类型,可以用type声明的变量来接收

    type mytype = { name : string } & { age : number} & { gender : string}
    let a : mytype = {
      name : 'zza',
      age : 26,
      gender : '男'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接口

    interface myInterface {
      name:string,
      age:number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)
    • 在TypeScript中,我们使用接口(Interfaces)来定义对象的类型。除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述

    接口是为变量或者类制定一个规则或者标准,实现时需要去遵守。

    变量声明接口类型时,属性要保持一致

    const a : myInterface = {
      name:'zza',
      age:26
    }
    
    • 1
    • 2
    • 3
    • 4

    类实现接口时,属性实现可以多但不能少

    class myClass implements myInterface{
      name: string
      age: number
      gender: string
      getInfo():string{
        return this.name
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    可选属性
    interface myInterface {
      name:string,
      age:number,
      gender?:string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    只读属性
    interface myInterface {
      name:string,
      age:number,
      readonly gender:string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    const 用来修饰变量,readonly 用来修饰属性

    任意属性

    一般用在对象变量上

    interface myInterface {
      name:string,
      age:number,
      [propName: string]: number | string;
    }
    const a : myInterface = {
      name:'zza',
      age:26,
      addr:'123'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    用在类中,意义不大

    class myClass implements myInterface{
      name: string 
      age: number 
      [propName: string]: number | string
      constructor(name:string,age:number,propName:number | string){
        this.name = name
        this.age = age
        this.propName = propName
      }
    }
    
    const obj = new myClass('zza',26,12)//myClass {name: "zza", age: 30, propName: 12}
    console.log(obj);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    可索引属性
    interface myInterface {
      name:string,
      age:number,
      [propName: number]: number
    }
    const a : myInterface = {
      name:'zza',
      age:26,
      123:0
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    接口继承

    extends

    interface myInterface {
      name:string,
      age:number,
    }
    interface myInterface2 extends myInterface{
      addr:string
    }
    
    class myClass {
      phone:string
      emil:string
    }
    interface myInterface3 extends myClass{
      call():void;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    类型别名和接口的区别

    1. 写法区别
    type A = number;
    type B = A | string | 'A'
    
    • 1
    • 2
    interface A {
      name: string
    }
    
    • 1
    • 2
    • 3

    合并写法

    type A = {
      name:string,
      age:number
    }
    type B = A & {
      gender:string
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    interface A {
      name:string,
      age:number
    }
    interface B extends A {
      gender:string
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 重复声明
      类型别名重复声明会报错
    interface A {
      name:string,
      age:number
    }
    interface  A {
      gender:string
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    class A {
      name : string
      constructor(name:string){
        this.name = name
      }
      getInfo(){
        console.log(this.name);
      }
    }
    
    class B extends A {
      age:number
      constructor(name:string, age:number){
        super(name)
        this.age = age
      }
      getInfo() {
        super.getInfo()
        console.log(this.age);
      }
    }
    
    const a = new B('zza',26)
    console.log(a);
    a.getInfo()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    readonly 修饰符
    • 只读属性必须在声明时或构造函数里被初始化。
    class Person {
      readonly name: string = 'abc'
      constructor(name: string) {
        this.name = name
      }
    }
    
    let john = new Person('John')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    公有、私有、受保护的修饰符
    public 公有

    属性和方法默认为公有,自己、类外和子类均可调用

    private 私有

    属性和方法只能在自己类中调用

    protected 受保护的

    属性和方法可以在自己和子类中调用

    class Person {
      protected name: string;
      constructor(name: string) {
          this.name = name;
      }
      protected getName():string{
        return this.name
      }
    }
    
    class Employee extends Person {
      private department: string;
    
      constructor(name: string, department: string) {
          super(name);
          this.department = department;
      }
    
      getWorkInfo() {
          return `我叫${this.getName()},我工作在${this.department}`;
      }
    }
    
    let aEmployee = new Employee('durban', '华盛顿');
    console.log(aEmployee.getWorkInfo());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    注意:readonly 与 上述修饰符不冲突,可以联合使用

    存取器
    class A{
      private _name:string 
      constructor(name:string){
        this._name = name
      }
      get name(){
        return this._name
      }
      set name(value:string){
        this._name = value
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    静态成员
    • 用static修饰的属性或方法
    • 存在于类本身而不是类的实例上
    class Person {
      name1: string = 'A'
      static name2: string = 'B'
    }
    
    console.log(Person.name2)
    console.log(new Person().name1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 在静态方法中可以调用静态的属性和方法,也可以调用this(可以将非静态的属性暴露),但不能用this获取非静态方法
    class A {
      private static age:string = '26'
      private name:string = 'zza'
      getInfo(){
        return this
      }
      static getStaticInfo(){
        return this
      }
    }
    
    console.log(A.getStaticInfo());
    console.log(new A().getInfo());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 类中有个内置的只读属性name,属于静态属性,在类中可以再声明一个name属性但不能修饰为静态属性。

    抽象类

    • 用abstract修饰的类是抽象类
    • 抽象类不能用来实例化对象,只能作为父类供子类来继承
    • 抽象类中可以添加普通属性和方法,也可以添加抽象属性和方法
    • 被抽象的属性和方法不允许有值或实现,也不允许被constructor赋值
    • 如果继承抽象类的子类不是抽象类,就必须将其中所有的抽象属性和方法具体化
    abstract class Animal {
      abstract name:string 
      constructor() {
      }
      abstract say():void;
      run():void{
        console.log('跑');
      }
    }
    
    abstract class sAnimal extends Animal{
      abstract age:number
    }
    
    class Dog extends sAnimal {
      name: string;
      age: number;
      run(): void {
        super.run()
      }
      say(): void{
        console.log('叫');
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    多态
    abstract class Animal {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
      abstract eat(): any;
      run() {
        console.log('动物跑');
      }
    }
    
    class Cat extends Animal {
      eat() {
        return "吃鱼";
      }
    }
    class Dog extends Animal {
      eat() {
        return "吃肉";
      }
      // run() {
      //   console.log('狗跑');
      // }
    }
    
    
    var cat: Animal = new Cat("猫");
    var dog: Animal = new Dog("狗");
    
    let fun: (x: Animal) => void = (x: Animal) => {
      console.log(x.name + x.eat());
    }
    
    fun(cat)
    fun(dog)
    
    cat.run()
    dog.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    接口和抽象类的区别

    区别:

    • 接口使用implemets实现,抽象类使用extends继承
    interface A {
      name : string
    }
    
    class B implements A {
      name: string //必须
      age : string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    abstract class A {
      abstract name : string
    } 
    
    class B extends A {
      name: string //必须
      age : number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 接口可以实现多个,以","分开,而继承只能有一个
    interface A1 {
      name : string
    }
    interface A2 {
      age : number
    }
    interface A3 {
      gender : string
    }
    class B implements A1,A2,A3 {
      name: string //必须
      age : number //必须
      gender: string //必须
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 抽象类中,可以有抽象方法及非抽象方法,接口中只能有抽象方法
    abstract class A {
      abstract name : string
      addr:string
    } 
    
    class B extends A {
      name: string //必须
      addr:string //非必须
      age : number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 抽象类可以继承抽象类也可以实现接口,而接口只可以继承接口和类,不可以实现接口和类

    共同点:

    • 都有抽象方法,都需要被实现
    • 都不能实例化
    • 抽象类可以被继承,接口也能被继承

    函数

    js:

    // 命名函数
    function fun1(x, y) {
      return x + y
    }
    
    // 匿名函数
    let fun2 = function(x, y) { 
      return x + y;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ts中增加类型声明:

    function fun1(x: number, y: number): number {
      return x + y
    }
    
    let fun2 = function(x: number, y: number): number { 
      return x + y
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对于给变量指定类型赋值的完整写法

    let myAdd2: (x: number, y: number) => number = 
    function(x: number, y: number): number {
      return x + y
    }
    
    • 1
    • 2
    • 3
    • 4
    可选参数和默认参数
    function fun(a: string='A', b?: string): string {
      if (b) {
        return a + '-' + b
      } else {
        return a
      }
    }
    
    console.log(fun('1', '2'))
    console.log(fun('3'))
    console.log(fun())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    剩余参数
    function letters(x: string, ...args: string[]) {
      console.log(x, args)
    }
    letters('abc', 'c', 'b', 'a')
    
    • 1
    • 2
    • 3
    • 4

    函数重载

    // 重载函数声明
    function add (x: string): string
    function add (x: number): number
    
    // 定义函数实现
    function add(x: string | number): string | number {
      if (typeof x === 'string') {
        return x
      } else if (typeof x === 'number') {
        return x
      }
    }
    const a : number = add(1)
    const b : string = add('1')
    console.log(a)
    console.log(b)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    泛型

    • 指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。

    函数泛型

    function fun<T,K>(a:T,b:K):T{
      console.log(b);
      return a 
    }
    
    fun<string,number>('123',123)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实际使用:

    function getNumberArr(value:number,count:number):number[] {
      const a : number[] = []
      for(let i = 0;i < count;i++){
        a.push(value)
      }
      return a
    }
    
    function getStringArr(value:string,count:number):string[] {
      const a : string[] = []
      for(let i = 0;i < count;i++){
        a.push(value)
      }
      return a
    }
    
    
    const arr = getNumberArr(123,10)
    console.log(arr[0].toFixed());
    
    const arr2 = getStringArr('123',10)
    console.log(arr2[0].length);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    利用泛型:

    function getArr<T>(value:T,count:number):T[] {
      const a : T[] = []
      for(let i = 0;i < count;i++){
        a.push(value)
      }
      return a
    }
    const arr3 = getArr<string>('123',10)
    const arr4 = getArr<number>(123,10)
    console.log(arr3[0].length);
    console.log(arr4[0].toFixed());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    泛型接口

    • 在定义接口时,为接口中的属性和方法定义泛型类型,在使用接口时,再指定具体的泛型类型
    interface A <T> {
      arr:T[]
      value:T
    }
    
    class B implements A<number>{
      arr:number[]
      value: number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用例子:

    interface IbaseCRUD <T> {
      data: T[]
      add: (t: T) => void
      getById: (id: number) => T
    }
    
    class User {
      id?: number; //id主键自增
      name: string; //姓名
      age: number; //年龄
    
      constructor (name, age) {
        this.name = name
        this.age = age
      }
    }
    
    class UserCRUD implements IbaseCRUD <User> {
      data: User[] = []
      
      add(user: User): void {
        user = {...user, id: Date.now()}
        this.data.push(user)
        console.log('保存user', user.id)
      }
    
      getById(id: number): User {
        return this.data.find(item => item.id===id)
      }
    }
    
    
    const userCRUD = new UserCRUD()
    userCRUD.add(new User('tom', 12)) 
    userCRUD.add(new User('tom2', 13))
    console.log(userCRUD.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    泛型类

    • 在定义类时, 为类中的属性或方法定义泛型类型 在创建类的实例时, 再指定特定的泛型类型
    class A <T> {
      default:T
      add:(x:T,y:T) => T
    }
    
    const a = new A<number>()
    a.default = 1
    a.add = (x:number,y:number) =>{
      return x + y
    }
    
    const b = new A<string>()
    b.default = '1'
    b.add = (x:string,y:string) =>{
      return x + y
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    泛型约束

    function fn <T>(x: T): void {
      console.log(x.length)  // 报错
    }
    
    • 1
    • 2
    • 3

    这时需要一个规则来约束这个泛型T ,让他可以使用length属性

    interface B {
      length:number
    }
    
    function fn <T extends B>(x: T): void {
      console.log(x.length)  // 报错
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:泛型约束中的extends意义上和实现相同,指T必须拥有接口B中的属性和方法

    interface B {
      length:number,
      add:(a:number,b:number)=>number
    }
    
    function fn <T extends B>(x: T): void {
      console.log(x.length) 
      console.log(x.add(100,200));
      
    }
    
    class C implements B{
      length: number
      add: (a: number, b: number) => number
    }
    
    fn<C>(
      {
      length:2,
      add:(x,y)=>{
        return x+y
      }
    }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    泛型工具

    keyof

    interface Foo {
      name: string;
      age: number
    }
    type T = keyof Foo // -> "name" | "age"
    
    const a : T = "name"
    const b : T = "age"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    type A = keyof any  //  type A = string | number | symbol
    
    • 1

    in

    type Keys = "a" | "b"
    type Obj =  {
      [p in Keys]: any
    } // -> { a: any, b: any }
    
    const a : Obj ={
      a:'123',
      b:123
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    infer

    • infer 声明一个类型变量并且对它进行使用,仅条件类型的 “extends” 子句中才允许 “infer” 声明。
    type A<T> = T extends (x: any) => infer P ? P : T;
    
    type B = (x:number)=>number
    
    const a : A<string> = '123'
    const b : A<B> = 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Partial 作用是将传入的属性变为可选项
    type myPartial<T> = { [P in keyof T]?: T[P] };
    
    interface A {
      a:string
      b:string
    }
    const a: myPartial<A> = {
      a:'132',
      // b:'123'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    Required 作用是将传入的属性变为必选项
    type myRequired<T> = { [P in keyof T]-?: T[P] }
    
    
    interface A {
      name:string
      age:number
      addr?:string
    }
    
    const a : myRequired<A> ={
      name:'zza',
      age:26,
      addr:'qewr'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    Record 后面的泛型就是对象键和值的类型
    type myRecord<K extends keyof any, T> = { [P in K]: T };
    
    const a : myRecord<string,number> = {
      // name:'zza',  报错
      age:26
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Pick 从 T 中取出 一系列 K 的属性
    type myPick<T, K extends keyof T> = { [P in K]: T[P] };
    
    interface A {
      name:string,
      age:number,
      addr:string
    }
    
    type B = 'name' | 'age'
    
    const a : myPick<A,B> = {
      name:'zza',
      age:26
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    ReturnType 获取返回值类型
    type myReturnType<T> = T extends (...args: any[]) => infer R ? R: T;
    
    type B = (x:number)=>number
    
    const a : myReturnType<string> = '123'
    const b : myReturnType<B> = 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    一键接入大模型:One-Api本地安装配置实操
    centos7安装WordPress
    专业135总分400+西安交通大学信息与通信工程学院909/815考研经验分享
    点云中值滤波函数(附python open3d 实现)
    APP兼容性测试如何测试?
    【ESP32 手机配网教程】
    jsp基础语法
    线程池原理与实现
    关于离子色谱仪的结构和应用原理分析
    七夕礼物送什么给男朋友好?七夕礼物清单
  • 原文地址:https://blog.csdn.net/qq_41278564/article/details/123859636