検索
ニュース

Microsoft、プログラミング言語「TypeScript 3.9」を公開速度、機能、使い勝手が向上

Microsoftは、オープンソースのプログラミング言語の最新版「TypeScript 3.9」を公開した。コンパイラの高速化やエディタ機能の強化、コーディング支援などの改良が行われている。

Share
Tweet
LINE
Hatena

 Microsoftは2020年5月12日(米国時間)、オープンソースのプログラミング言語の最新版「TypeScript 3.9」を公開した。

 TypeScriptは、静的型付けができる言語で、JavaScriptのスーパーセットだ。ECMA規格に従った最新のJavaScriptの機能を、古いWebブラウザやランタイムが扱えるようにコンパイルすることもできる。

 TypeScript 3.9は、NuGetを使うか、次のコマンドラインのように、npmを使ってインストールできる。

npm install typescript

 TypeScript 3.9は「Visual Studio 2019」「Visual Studio 2017」の他、「Visual Studio Code」と「Sublime Text」でも利用できる。TypeScript 3.9の主な特徴は次の通り。

推論とPromise.allの改良

 TypeScriptの最近のバージョン(3.7など)では、「Promise.all」や「Promise.race」のような関数の宣言が更新された。だが、これに伴って幾つかの副作用が生じた。特に、nullまたはundefinedの値を組み合わせた場合が顕著だった。

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(); // uh oh
//  ‾‾‾‾
// Object is possibly 'undefined'.
}

 これは奇妙な挙動だ。sealExhibitがundefinedを含むことで、lionの型にundefinedが含まれてしまっている。

 TypeScript 3.9では、推論プロセスの改良によってこの問題が解決された。上のようなエラーは発生しなくなっている。

速度の改善

 TypeScript 3.9では、速度の改善が多数行われた。「material-ui」や「styled-components」のようなパッケージで編集/コンパイルが極めて遅いことが分かったため、TypeScriptチームはパフォーマンス向上に重点的に取り組んだ。大きな結合、交差、条件型、マップ型に関わる問題がある特定のケースを最適化する一連のプルリクエストにより、踏み込んだ改善を図った。

 各プルリクエストは、特定のコードベースのコンパイル時間を5〜10%程度短縮する。全体として、material-ui-stylesプロジェクトのコンパイル時間が25%程度短縮されたと、TypeScriptチームは考えている。

 エディタによるファイル名変更に時間がかかる場合もあったが、この問題も解決された。

//@ts-expect-errorコメント

 例えば、TypeScriptでライブラリを作成していて、パブリックAPIの一部として、「doStuff」という関数をエクスポートするとする。この関数の型は、他のTypeScriptユーザーが型チェックエラーを取得できるように、2つの文字列を取ると宣言するが、JavaScriptユーザーに有用なエラーを出力するため、ランタイムチェックも行う(開発ビルドにおいてのみかもしれない)。

function doStuff(abc: string, xyz: string) {
    assert(typeof abc === "string");
    assert(typeof xyz === "string");
    // do some stuff
}

 このため、TypeScriptユーザーはこの関数を誤用すると、有用な赤いチルダとエラーメッセージを取得する。JavaScriptユーザーもアサーションエラーを取得する。この挙動をテストするため、ユニットテストを作成する。

expect(() => {
    doStuff(123, 456);
}).toThrow();

 残念ながら、テストをTypeScriptで作成すると、TypeScriptはエラーを提供する。

    doStuff(123, 456);
//          ‾‾‾
// error: Type 'number' is not assignable to type 'string'.

 そのため、TypeScript 3.9では、「// @ts-expect-error」コメントという新機能が導入された。行の前に// @ts-expect-errorというコメントを配置すると、TypeScriptは、そうしたエラーの報告を抑制する。だが、エラーがない場合は、// @ts-expect-errorが不要だったと報告する。

 簡単な例でいえば、次のコードは問題ない。

// @ts-expect-error
console.log(47 * "octopus");

 だが、次のコードは、

// @ts-expect-error
console.log(1 + 1);

 次のエラーを発生させる。

Unused '@ts-expect-error' directive.

条件式での呼び出されない関数のチェック

Copyright © ITmedia, Inc. All Rights Reserved.

PREVIEW
'; }else{ mask.innerHTML = '
画像をご覧いただくには会員登録が必要です
' + btn_txt + '
'; } if((_preview && location.hash.indexOf('maskoff') !== -1) || (typeof itmIdLogin !== 'undefined' && itmIdLogin == 1)){ img.style.visibility = 'visible'; }else{ nxt.parentNode.insertBefore(mask,nxt); } } } }; (function(d){ var _preview = d.domain.match(/(preview|broom|localhost)/); window.addEventListener('load',function(){ // islLogin 呼出済|preview if(d.getElementById('isLogin') || _preview){ mask_images({ sc:'0c1c43111448b131d65b3b380041de26f2edd6264ee1c371184f54d26ab53365', lc:'7d7179c146d0d6af4ebd304ab799a718fe949a8dcd660cd6d12fb97915f9ab0a', ac:'1a599d548ac1cb9a50f16ce3ba121520c8ab7e05d54e097bfa5b82cb5a328a0f', cr:'2c93f81754142e105c8bca17824745d14c8c4d69e9d7ede513e5530546e97641', bc:1 }); // islLogin なし }else{ var js = mask_images.setISLOGIN('//status.itmedia.co.jp/isLoginAIT.cgi','0c1c43111448b131d65b3b380041de26f2edd6264ee1c371184f54d26ab53365'); js.addEventListener('load',function(){ mask_images({ sc:'0c1c43111448b131d65b3b380041de26f2edd6264ee1c371184f54d26ab53365', lc:'7d7179c146d0d6af4ebd304ab799a718fe949a8dcd660cd6d12fb97915f9ab0a', ac:'1a599d548ac1cb9a50f16ce3ba121520c8ab7e05d54e097bfa5b82cb5a328a0f', cr:'2c93f81754142e105c8bca17824745d14c8c4d69e9d7ede513e5530546e97641', bc:1 }); }); } }); })(document);
LOADING
'; w.removeEventListener('scroll',arguments.callee,false); htmlRequest(_xhrfile,_idname); elem.setAttribute('data-status','true'); console.log('finished : ' + _idname); }else{ // console.log('retry : ' + _idname); } }else{ e_loader.innerHTML = '
LOADING
'; w.removeEventListener('scroll',arguments.callee,false); htmlRequest(_xhrfile,_idname); elem.setAttribute('data-status','true'); console.log('finished : ' + _idname); } } }; w.addEventListener('scroll',scrolling,false); // スクロールイベント scrolling(); // スクロールイベント(閲覧位置が半端な場合のために 1 回実行させる) }; w.addEventListener('load',loading,false); // LOAD 後に実装 };