来看看TypeScript 4.3.5 的一些新增属性吧~

4.3.5 playground地址

4.2.3 playground地址

模版字符串的ts

  1. typescript 帮我们推断出字符串
type Colors = "red" | "green";
type Size = "big" | "small";
type Result = `${Colors | Size} fish`; // "red fish" | "green fish" | "big fish" | "small fish"
复制代码
  1. 在函数中使用
// 模版字符串
const Demo = (s: string): `hahaha ${string}` => {
  return `hahaha ${s}`;
};

type DemoType = typeof Demo; // type Demo = (s: string) => `hahaha ${string}`
复制代码

“#” 声明私有属性/方法

在类中使用 “#” 使得属性/方法 在运行时成为真正的私有元素

class Foo {
    age = 58
    private length = "吐司"
    #name = "吐司"
    static #staticName = "吐司"

    sayHello(){
        console.log('hello world')
    }

    private sayYes(){
        console.log('yes')
    }

    #sayNo(){
        console.log('No')
    }

}

// 属性
new Foo().age
new Foo().length    
//        ~~~~~~
// Property 'length' is private and only accessible within class 'Foo'.
new Foo().staticName  
//        ~~~~~~
// Property 'staticName' does not exist on type 'Foo'.
new Foo().name  
//       ~~~~~~
// Property 'name' does not exist on type 'Foo'.

// 方法
new Foo().sayHello()
new Foo().sayYes()  
//        ~~~~~~
// Property 'sayYes' is private and only accessible within class 'Foo'.
new Foo().sayNo()   
//        ~~~~~~
// Property 'sayNo' does not exist on type 'Foo'

复制代码

继承的子类也不能访问

class FooChild extends Foo {
    sayFatherAge(){
        console.log(this.age)
        console.log(this.length)  
        //               ~~~~~~
        // Property 'length' is private and only accessible within class 'Foo'.
        console.log(this.staticName)  
        //               ~~~~~~~~~
        // Property 'staticName' does not exist on type 'FooChild'.
    }
}
复制代码

抽象类 ConstructorParameters

ConstructorParameters 帮我们获取抽象类的 constructor 参数

(抽象类文档直达)

abstract class CCC {
    constructor(name: string, age: number, beauty: boolean){
    }

    abstract getName(): string
}

type CCCType = ConstructorParameters<typeof CCC> // [name: string, age: number, beauty: boolean]

复制代码

第二个泛型

4.2及之前版本如下代码不能正确识别 第二个泛型C

// 4.2 及以前, 写法
function makeUnique<T extends String | Number>(collection: Set<T> | T[]): Set<T> | T[];
// 4.3
function makeUnique<T extends String | Number, C extends Set<T> | T[]>(collection: C): C;
复制代码
function makeUnique<T extends String | Number, C extends Set<T> | T[]>(
  collection: C,
): C {
  if (collection instanceof Set) {
    return collection;
  }

  collection.sort((a,b) => Number(a) < Number(b) ? -1 : 1)
  //         ~~~~~~
  // Property 'sort' does not exist on type 'C'
  

  // 数组的去重操作,可忽略其实现
  for (let index = 0; index < collection.length; index++) {
    const element = collection[index];
    //                         ~~~~~~
    // Element implicitly has an 'any' type because expression of type 'number' can't be used to index type 'Set<T> | T[]'.
    
    for (
      let startIndex = index + 1;
      index < collection.length - startIndex;
      startIndex++
    ) {
      const nextElement = collection[startIndex];
      if (element === nextElement) {
        collection.splice(index + 1, 1);
      } else {
        break;
      }
    }
  }


  return collection;
}
复制代码

检查promise 的 truthy

文档说如果直接调用Promise 判断真假,会报错
但是我在playground 尝试并没有发现

async function foo(): Promise<boolean> {
  return false;
}
async function bar(): Promise<string> {
  if (foo()) {
    //  ~~~~~
    // Error!
    // This condition will always return true since
    // this 'Promise<boolean>' appears to always be defined.
    // Did you forget to use 'await'?
    return "true";
  }
  return "false";
}
复制代码

static允许修改类本身索引签名

索引签名允许我们对值设置比显式声明的类型更多的属性, 但是之前我们只能在类的实例端声明,代码如下

class Foo {
  age = 29;

  [propName: string]: string | number | undefined
}

let instance = new Foo();
instance['otherthing'] = '我是name'

// 如果尝试直接修改类本身,则会报错
Foo["something"] = '我是长度'
// ~~~~~
// Element implicitly has an 'any' type because expression of type '"something"' can't be used to index type 'typeof Foo'.
复制代码

4.3 使得我们该索引签名添加 static 关键字,从而允许直接修改类本身的属性, 但是这样不能修改实例的

class Foo {
  age = 29;

  static [propName: string]: string | number | undefined
}

let instance = new Foo();
instance['otherthing'] = '我是name'
//        ~~~~~~~~~~
// Element implicitly has an 'any' type because expression of type '"otherthing"' can't be used to index type 'Foo'.

Foo["something"] = '我是长度'
复制代码

类的静态方面的索引签名和实例方面的索引签名应用的规则相同,也就是说,其他所有的静态属性都必须和索引签名类型相同


class Foo {
  static age = 29;
  //     ~~~
  // Property 'age' of type 'number' is not assignable to string index type 'string | undefined'

  static [propName: string]: string | undefined
}

Foo["something"] = '我是长度'
复制代码

枚举类型不能与永远不相等的数字进行比较

enum AA {
  A = 0,
  B = 1
}

const demo = (val: AA) => {
  if(val === 3){
    // ~~~~~~~ 4.3版本这里会类型报错
    // This condition will always return 'false' since the types 'AA' and '3' have no overlap.

    // do something
  }
}
复制代码

对此的变通方案

  1. 重写枚举,将枚举重新声明为不平凡(non-trivial )的值
enum AA {
  A = +0,
  B = 1
}

const demo = (val: AA) => {
  if(val === 3){
    // do something
  }
}
复制代码
  1. 使用 as, 对值进行类型断言
enum AA {
  A = 0,
  B = 1
}

const demo = (val: AA) => {
  if((val as number) === 3){
    // do something
  }
}
复制代码
  1. 使用联合类型 并 添加注释
enum AA {
  A = 0,
  B = 1
}

// Include 3 in the type, if we're really certain that 3 can come through.
const demo = (val: AA  | 3) => {
  if((val as number) === 3){
    // do something
  }
}
复制代码

其他

  1. 搭配新版内部版本vscode, import 类型提示更智能 vscode地址
  2. 支持@link tag
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享