TypeScript 4.4

TypeScript 4.4

https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/

代入された判別式の control flow analysis

以前の TypeScript では、type guard の判別式を変数に代入した場合、その判別式は機能しない。

function foo(arg: unknown) {
  const argIsString = typeof arg === "string";
  if (argIsString) {
    console.log(arg.toUpperCase());
    //              ~~~~~~~~~~~
    // Error! Property 'toUpperCase' does not exist on type 'unknown'.
  }
}

TypeScript 4.4 では、変数をチェックし、内容が判別式であれば変数の型を絞り込むことができる。

シンボルとテンプレート文字列としての Index Signature

TypeScript 4.4 からはシンボルとテンプレート文字列パターンが Index Signature として使用できる

interface Colors {
  [sym: symbol]: number;
}

const red = Symbol("red");

let colors: Colors = {};

colors[red] = 255;
interface Options {
    width?: number;
    height?: number;
    // 任意の`data-`から始まる文字列をプロパティのキーとして使用できる
    [optName: `data-${string}`]: unknown;
}

let option: Options = {
    width: 100,
    height: 100,
    "data-blah": true
};

useUnknownInCatchVariablesオプション

catch句の変数の型をanyからunknownに変更するオプション

try {
} catch (err) {
  // unknown
}

strictオプション下では自動的にオンになる。

exactOptionalPropertyTypesオプション

多くの JavaScript コードでは、存在しないプロパティとundefinedを値として持つプロパティは同一のものとして扱われる。そのため TypeScript でも、オプショナルプロパティは、undefinedとのユニオンタイプとして考えられてきた。例えば、

interface Person {
  name: string;
  age?: number;
}

これは下記と同様:

interface Person {
  name: string;
  age?: number | undefined;
}

exactOptionalPropertyTypesオプション下では、オプショナルプロパティはundefinedとのユニオンタイプを追加しない。存在しないプロパティと区別される。

const p: Person = {
  name: "Daniel",
  age: undefined, // Type 'undefined' is not assignable to type 'number'.(2322)
};

static ブロック

ECMAScript プロポーザルの static ブロックをサポート:

class Foo {
    static count = 0;

    // This is a static block:
    static {
        if (someCondition()) {
            Foo.count++;
        }
    }
}