えぐろぐ

https://twitter.com/eggpogg

TypeScript3.9がリリースされていたのでリリースノートの確認

TypeScriptを触ることが今年すこーしだけあって,書きやすくてよかったので,リリースも追っていこうと思いリリースノートを確認してみる.

TypeScriptの3.9の正式版は5/13にリリースされている.

github.com

詳しい変更点はブログにまとまっている. www.typescriptlang.org

今回の大きな変更点は

  • Promise.all 関数の推論処理の修正
  • 速度の改善
  • // @ts-expect-error コメントの追加
  • 条件式で関数呼び出しを忘れている場合のチェックを追加
  • エディターの改善
  • 破壊的変更

Promise.all 関数の推論処理の修正

Promise.allを使用した場合の返り値の型推論が修正された.

いままでは,SealExhibitのPromiseの返り値のundefinedがLionExibit側にも影響を及ぼしてたみたい.

interface Lion {
  roar(): void;
}

interface Seal {
  singKissFromARose(): void;
}

async function visitZoo(
  lionExhibit: Promise<Lion>,
  sealExhibit: Promise<Seal | undefined>
) {
  let [lion, seal] = await Promise.all([lionExhibit, sealExhibit]);
  lion.roar();
  //  ~~~~
  // 以前まではここで,undefinedの可能性があるとのことでエラーになっていた.
}

速度の改善

さまざまな速度改善が行われたようだ.

  • コンパイル処理の改善
  • エディター側の改善

特にマテリアルUI周りのコンパイルを40%改善したとのこと.

// @ts-expect-error コメントの追加

TypeScriptでテストを書いている場合に,型チェックのコードのテストを書くことができないことがある. それを回避できるように@ts-expect-errorを作ったとのこと.

// このような関数がある場合に,
function hoge(aaa: string, bbb: string) { console.log(aaa + bbb); }


// 引数のテストを書く場合に,TypeScriptの型チェックでエラーになり弾かれる.
// // @ts-expect-error を追加することでテストを書くに事ができる.
expect(() => {
  // @ts-expect-error
  hoge(123, 456);
}).toThrow();

条件式で関数呼び出しを忘れている場合のチェックを追加

hogeの関数の呼び出し時に,()のつけ忘れで常にtrueになってしまう. 3.9では以下のような不具合を検知してエラーになるようになった.

function hoge(): Boolean { return false; };


// 今まで
hoge ? console.log("true") : console.log("false");
// ~~~~~
//  This condition will always return true since the function is always defined. Did you
//  mean to call it instead?(2774)
--- result
[LOG]: true 


// これから
hoge() ? console.log("true") : console.log("false");
// 関数呼び出しにする必要がある.
--- result
[LOG]: false

エディターの改善

VSCode,VSのエディタの改善が行われた.
僕はIntellij派なので,流し読み.

CommonJS Auto-Imports in JavaScript

いままでは,importで統一しようと思っていたけど,

import * as fs from "fs";

requireも必要なので,使用状況を検出して対応するようにしたとのこと.

const fs = require("fs");

Code Actions Preserve Newlines

コードアクションを使った場合に,空行をリファクタリングして削除していたが,保持するように対応したとのこと.

今までは空行が削除されていた.

https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2020/03/printSquaresWithoutNewlines-3.9.gif.gif

これからは,空行を保持されるようになった.

https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2020/03/printSquaresWithNewlines-3.9.gif.gif

Quick Fixes for Missing Return Expressions

アロー関数時にreturnをつけるActionが追加された. f:id:eggpogg:20200524163813p:plain

Support for “Solution Style” tsconfig.json Files

プロジェクトのルートにtsconfig.jsonを設置しているが,いろいろなjsonを読み込むだけの管理ファイルとして活用している場合に,このプロジェクトがTypeScirptでかかれていると理解してもらえなかったのを理解してもらえるようにした.

ということであっているのか?

破壊的変更

Parsing Differences in Optional Chaining and Non-Null Assertions

定義

var foo: Foo | null;

interface Foo {
  bar:  Bar
}

interface Bar {
  baz: string
}

今まではfoonull | undefinedのときにクラッシュしていた.

foo?.bar!.baz
-> エラー

以前まで,以下のようなJSに変換されていた.
!をいれることで,foo?.barという塊とみなされて,bazアクセス時にエラーになっていた.

(foo === null || foo === void 0 ? void 0 : foo.bar).baz

これからは,以下のように変換されるようになった.
なのでfoo?.bar.bazfoo?.bar!.bazでJSへの変換が同じになった.

foo === null || foo === void 0 ? void 0 : foo.bar.baz

!の考え方が,今まではchainで繋いできたものを()で囲んでnullundefinedを削除してきたのを,対象が?operatorがついているものだけに絞られたようだ.

} and > are Now Invalid JSX Text Characters

JSX使用時の,}>の文字の使用禁止をより強制するようにした.
また,エラーメッセージも表示するようにしたとのこと.

Stricter Checks on Intersections and Optional Properties

今までは,以下の処理でy=xがBとCに互換性があったので,エラーではなかった. が,今後は厳密にチェックが入るようになりエラーになるようになったとのこと.

interface A {
  a: number; // notice this is 'number'
}

interface B {
  b: string;
}

interface C {
  a?: boolean; // notice this is 'boolean'
  b: string;
}

declare let x: A & B;
declare let y: C;

y = x;

Intersections Reduced By Discriminant Properties

今までは以下のコードはエラーではなかった.
CircleにもSquareにもkindが含まれており,適切な処理ができていなかったので,これからはエラーとして処理されるようになるとのこと.

declare function smushObjects<T, U>(x: T, y: U): T & U;

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

declare let x: Circle;
declare let y: Square;

let z = smushObjects(x, y);
console.log(z.kind);

f:id:eggpogg:20200525084114p:plain

Getters/Setters are No Longer Enumerable

今までは,プロパティの列挙がデフォルトで可能(true)だったが,ECMAScriptの仕様に合わせて,デフォルトで不可能(false)に変更したとのこと.

ref: developer.mozilla.org

Type Parameters That Extend any No Longer Act as any

今までは,any型のextendsの場合はどんなプロパティでも参照することができたが,これからはエラーとして処理するようになる. 保守的なアプローチで対応したとのこと.

function foo<T extends any>(arg: T) {
  arg.spfjgerijghoied;
}

export * is Always Retained

今まではexportで未使用なものは,JS変換時に削除されていた. これからは,削除しないようになったとのこと.

More libdom.d.ts refinements

libdom.d.tsが引き続き改善されている. DOM仕様からWeb IDLに移行中とのこと.

締め

最初リリースノートを見たときに,破壊的変更がindex似合ったときは驚いたが,読んでみると確かにと思うところは多かったので,臆せず読んで理解することは大切だと再確認した.
Null制御あたりはJavaよりもJSの方が苦しめられてきたので,もっとガッチガチに固めてほしいなと感じる.

1週間ぶりにブログを書く.
ブログって日々の生活の中であれを書こうと思って,常にインプットをしてどういう風に書こうか考えていないと無理なんだなと感じた.