TypeScript Blogの元ポスト: https://devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/
個人の判断で説明を省略したり補足したりするので、完全な翻訳はない。元ポストも合わせて参考してください。
Optional Chaining
TLDR: 大体 Ruby の a&.property
、Swift / Kotlin の a?.property
にあたる。
この提案もうES Stage 3 に行ってるので、 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining か ES仕様も参考になる。
.
属性評価
let foo: null | undefined | { bar: { baz(): number }};
let x = (foo === null || foo === undefined) ?
undefined :
foo.bar.baz();
// equivalient to
let x = foo?.bar.baz();
[]
属性評価
function tryGetFirstElement<T>(arr?: T[]) {
return arr?.[0];
// equivalent to
return (arr === null || arr === undefined) ?
undefined :
arr[0];
}
()
関数呼び出し
function tryCall(foo?: () => void)) {
foo?.();
// equivalent to
if (foo !== null && foo !== undefined) {
foo();
}
}
注意点
short circuit評価は そのoptional chain式の内部だけに 存在する、式全体までshort circuitになるわけではない。
例:
let foo: null | { val: number;}
let cez: () => number;
let bar = foo?.val / cez();
// cez() はfooの値と関係なく実行されて、number型になる。
// またfoo?.val の型は undefined|number になるため、
// tscのstrictNullChecks オプションがtrueの場合 `/` のところでタイプエラーになる。
Nullish Coalescing
let x = foo ?? bar();
// equivalent to
let x = (foo !== null && foo !== undefined) ?
foo :
bar();
foo
が null
か undefined
の場合のみ、右の式が評価されて全体の値になる。
||
との違い: ||
は左が 0
NaN
''
の場合でも右の式を評価してしまう。
Assertion Functions
TS3.7以前、assertion関数 (特定の条件が満たされなければthrowする) の型をうまく表現できなかった。
TS3.7から、関数戻り値のところに asserts CONDITION
書くことで、"例外投げなければconditionが成り立つ" とコンパイラに保証することができるようになる。
// 文法:
function foo(x: unknown): asserts CONDITION {}
// CONDITIONの例
function assertIsStr(x: unknown): asserts x is string {
if (typeof x !== 'string') throw ...;
}
function bar(x: unknown) {
assertIsStr(x);
// ここまで来れたら、CONDITION ("x is string") が成立するとされる
return x.toUppercase();
}
Better Support for never
-Returning Functions
// 戻ることがない関数専用の戻り値: never
// (でも型推論で自動でneverにならないみたい、自分でneverを指定することが必要)
// node.jsのTS型宣言に、process.exit() もnever型を返す
function neverReturn(): never {
throw new Error();
}
// TS3.7以前に、neverを返す関数を呼び出しても、コントロールフロー分析が「戻らないこと」を意識しなかった
function foo() {
neverReturn();
return 1; // TS3.7から、ここが unreachable code になる
}
(More) Recursive Type Aliases
TS3.7以前、Type Alias (おそらくMapped Type含めて) に(直接・間接ともに)再帰的にType 使うと妙なエラーが出たりしてた。
TS3.7から、↓のように「再帰Readonly」みたいな型を簡単に書けるようになる。
export type DeepReadonly<T> = T extends (string | number | symbol | null | undefined | void | RegExp | Function)
? T
: T extends Map<infer K, infer V>
? ReadonlyMap<K, V>
: T extends Set<infer E>
? ReadonlySet<DeepReadonly<E>> // pre-3.7: Type "DeepReadonly" is not generic
: T extends Array<infer E>
? readonly DeepReadonly<E>[] // pre-3.7: Type "DeepReadonly" is not generic
: T extends {}
? { readonly [k in keyof T]: Readonly<T[k]> }
: never;
--declaration and --allowJs
TS3.7以前、tscの allowJs
オプションで JSをコンパイル (トランスパイル) する場合、.d.ts
を生成できなかった。
TS3.7から、入力がjsでもtscが推論したタイプで .d.ts
を生成するようになる。
Uncalled Function Checks / Function Truthy Checks
TS3.7から、関数型の値 foo
を呼び出さずに if (foo) { ... }
のように書くと、コンパイルエラーが出るようになる。(メソッド呼び出しも同様。具体のエラー条件と回避方法は元のポストに)
// @ts-nocheck
in TypeScript Files
TS3.7から、このコメントがTSファイルでも効くようになる。
Build-Free Editing with Project References
project references
という機能の強化らしい、私使ったことないのでよくわからなかった。
Semicolon Formatter Option
tscとVS Codeの内蔵フォマート機能の強化らしい、私 prettier
だけ使ってるのでよくわからなかった。