4.3.5 playground address

Holdings playground address

Template string ts

  1. Typescript helps us infer strings
type Colors = "red" | "green";
type Size = "big" | "small";
type Result = `${Colors | Size} fish`; // "red fish" | "green fish" | "big fish" | "small fish"
Copy the code
  1. Used in functions
// Template string
const Demo = (s: string) :`hahaha The ${string}`= > {return `hahaha ${s}`;
};

type DemoType = typeof Demo; // type Demo = (s: string) => `hahaha ${string}`
Copy the code

“#” declares private properties/methods

Using “#” in a class makes attributes/methods truly private at run time

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

    sayHello(){
        console.log('hello world')}private sayYes(){
        console.log('yes'#)}sayNo(){
        console.log('No')}}/ / property
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'.

/ / method
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'

Copy the code

Inherited subclasses are also not accessible

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'.}}Copy the code

An abstract class ConstructorParameters

ConstructorParameters help us get the constructor parameter of an abstract class

(Abstract class document direct)

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

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

Copy the code

Second generic

4.2 and earlier versions of the following code do not correctly recognize the second generic C

// 4.2 and before
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;
Copy the code
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'
  

  // Delete the array, ignoring its implementation
  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;
}
Copy the code

Check promise’s Truthy

The documentation says that an error will be reported if the Promise is called directly to determine whether it is true or false, but I didn’t find that in my attempts on 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";
}
Copy the code

Static allows you to change the index signature of the class itself

Index signatures allow us to set more attributes on values than explicitly declared types, but previously we could only declare them on the instance side of the class, as shown below

class Foo {
  age = 29;

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

let instance = new Foo();
instance['otherthing'] = 'I am the name'

// If you try to modify the class itself directly, an error is reported
Foo["something"] = 'I am length'
/ / ~ ~ ~ ~ ~
// Element implicitly has an 'any' type because expression of type '"something"' can't be used to index type 'typeof Foo'.
Copy the code

4.3 allows us to add the static keyword to the index signature, which allows us to directly modify the properties of the class itself, but not the instance

class Foo {
  age = 29;

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

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

Foo["something"] = 'I am length'
Copy the code

The index signature of the static aspect of the class applies the same rules as the index signature of the instance aspect, that is, all other static attributes must be of the same type as the index signature


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"] = 'I am length'
Copy the code

Enumeration types cannot be compared with numbers that are never equal

enum AA {
  A = 0,
  B = 1
}

const demo = (val: AA) = > {
  if(val === 3) {// ~~~~~~~ 4.3 type error
    // This condition will always return 'false' since the types 'AA' and '3' have no overlap.

    // do something}}Copy the code

Workarounds for this

  1. Rewrite enumerations to redeclare them as non-trivial values
enum AA {
  A = +0,
  B = 1
}

const demo = (val: AA) = > {
  if(val === 3) {// do something}}Copy the code
  1. Using AS, type assertions are made on values
enum AA {
  A = 0,
  B = 1
}

const demo = (val: AA) = > {
  if((val as number) = = =3) {// do something}}Copy the code
  1. Use union types and add comments
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}}Copy the code

other

  1. With the new internal version vscode, the import type hints for smarter vscode addresses
  2. Support @ the link tag