TypeScript 4.4

September 04, 2021

typescript

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

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

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

ts
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 として使用できる

ts
interface Colors {
[sym: symbol]: number;
}
 
const red = Symbol('red');
 
let colors: Colors = {};
 
colors[red] = 255;
ts
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に変更するオプション

ts
try {
} catch (err) {
var err: unknown
}

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

exactOptionalPropertyTypesオプション

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

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

これは下記と同様:

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

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

ts
interface Person {
name: string;
age?: number;
}
 
const p: Person = {
Type '{ name: string; age: undefined; }' is not assignable to type 'Person' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'age' are incompatible. Type 'undefined' is not assignable to type 'number'.2375Type '{ name: string; age: undefined; }' is not assignable to type 'Person' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'age' are incompatible. Type 'undefined' is not assignable to type 'number'.
name: 'Daniel',
age: undefined,
};

static ブロック

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

ts
class Foo {
static count = 0;
}