「Announcing TypeScript 4.9 Beta」を読む
前回に引き続き、Announcing TypeScript 4.9 Betaを読んでいきます。
(関心が続く限り続けていきたいです。。。)
The satisfies Operator
新しく「型推論に影響せず、型チェックのみを行う」演算子が追加されました。
以下の例は、Record<string, number | number[]>
型に代入可能であることをチェックしますが、その結果は{hoge: number, fuga: number[]}
型に推論されます。
const sample = {
hoge: 3,
fuga: [2, 4, 6],
} satisfies Record<string, number | number[]>;
sample.fuga[2]; // 4
上記の例は、sampleにRecord<string, number | number[]>
型を付与してしまうと、sample.fuga
がnumber
型の可能性があるため、エラーとなります。
const sample: Record<string, number | number[]> = {
hoge: 3,
fuga: [2, 4, 6],
};
sample.fuga[2]; // ERROR
これがどの程度有用なのかは分からないのですが…個人的には代入の時よりも、ある変数がある型になっていることをチェックするだけのために使うと役立ちそうだな~と思いました。
例えば、パターンマッチングで、網羅性を調べられます。ライブラリを入れずともできるので、手軽ですね。
const sample = (a: 'b' | 'c' | 'd') => {
if (a === 'b') return 1;
if (a === 'c') return 2;
a satisfies never; // ERROR
};
後、関数の関数を呼び出した時とかもチェックできます。
const sample = (f: (a: string) => (b: number) => void) => {
f('hoge')(3) satisfies void;
f('hoge') satisfies void; // ERROR
};
あんまりなさそうですが…「あれ?これでいいっけ?」と思った時に書いてもいいかもしれません。
ただし、書いた瞬間は多少満足感があったのですが、落ち着いてみるとコードが汚くなり、可読性は落ちそうに感じてしまいます。。。
一応、await
忘れ対策もできるっちゃできます。
const asyncFunc = async () => {};
const sample = async () => {
await asyncFunc() satisfies void;
asyncFunc() satisfies void; // ERROR
};
けど、await
忘れるならsatisfies
をつけ忘れそうです。現実的ではないですかね。。。
Unlisted Property Narrowing with the in Operator
明示的にリストアップされていないPropertyに対しても、in
演算子の絞り込みでNarrowingするようになりました。(今までできなかったんだ。。。)
以下のように、明示的にPropertyが宣言されていれば、従来からin
演算子で絞り込みが効いていました。
const sample = (a: {b: string} | {c: number}) => {
if ('b' in a){
a; // {b: string}
a.b; // string
}
};
明示的に宣言されていないと、Narrowingされませんでしたが、それがobject & Record<"b", unknown>
型にNarrowingされます。
const sample = (a: object) => {
if ('b' in a){
a.b; // 4.8まではエラー
}
};
Checks For Equality on NaN
バグになりやすい、NaNとの等値比較をエラー扱いするようになりました。ちゃんとisNaNを使おうと注意してくれます。
const sample = (a: number) => {
if (a === NaN) return undefined; // ERROR
return a + 1;
};
File-Watching Now Uses File System Events
ファイルの変更を監視する仕組みが、ポーリングからOSのファイルシステムイベントになるそうです。それまでの経緯などが書かれていました。
Better Types for Promise.resolve
Promise.resolve
の戻り値型が変わりました。
いくつか試したところ、以下のコードで差が出ました。
以前はT | PromiseLike<T>
を受け取ってPromise<T>
を返却していましたが、ちゃんとAwaited
でPromiseを解決するようにしたみたいです。
自分が使っている限りでは困りませんが、ライブラリ開発者の方とかは気にする必要があるのかもしれないですね~
const sample = () => {
// 4.8 ではPromise<Promise<unknonw>>型
// 4.9beta ではPromise<unknonw>型
const a = Promise.resolve({} as Promise<Promise<unknown>>);
};
その他
上記以外にも項目がありますが、リンクだけまとめます。