コンテンツにスキップ

[TypeScript] 2.9

TypeScript2.9のリリース内容まとめ

Support number and symbol named properties with keyof and mapped types

HAD BETTER NORMAL

index typesやmapped typesnumbersymbolのnamed propertiesをサポートするようになった。

バージョン named propertiesでサポートする型
2.8以前 string
2.9 string, number, symbol
const One = Symbol();
interface A {
  one: string;
  1: string;
  [One]: string;
  [x: string]: string;
}
type KeyOfA = keyof A;
// v2.8: string
//   * 1はstringとして扱われるため "one" | "1"
//   * symbolは未対応なので無視
//   * stringのindex typesに "one" | "1" も含まれるのでまとめてstring
// v2.9: string | number | unique symbol
//   * keyofがnumberとsymbolをサポートするようになった
//   * "one"はstringのサブタイプとして統合された
const Two = Symbol();
interface B {
  two: string;
  2: string;
  [Two]: string;
  [x: number]: string;
}
type KeyOfB = keyof B;
// v2.8: "two" | "2"
//   * 2はstringとして扱われるため "two" | "2"
//   * symbolは未対応なので無視
//   * numberのindex typesはサポート外のため無視
// v2.9: number | unique symbol | "two"
//   * keyofがnumberとsymbolをサポートするようになった
//   * 2はnumberのサブタイプとして統合されたが、"two"と[Two]はnumberでないため残る
const Three = Symbol();
interface C {
  three: string;
  3: string;
  [Three]: string;
}
type KeyOfC = keyof C;
// v2.8: "three" | "3"
//   * 3はstringとして扱われるため "three" | "3"
//   * symbolは未対応なので無視
// v2.9: unique symbol | "three" | 3
//   * index typesは無いので、named propertiesがそのままunion typesとして適応される

index typesがstring以外の場合でmapped typesを用いても、index typesの型が尊重される。

interface D {
  hoge: string;
  [x: number]: string;
}
type ReadonlyType<T> = { readonly [P in keyof D]: D[P] };
declare const tmp: ReadonlyType<D>;
const r = tmp[10];
// v2.8: TS7017: Element implicitly has an 'any' type because type 'ReadonlyType ' has no index signature
//   * numberのindex typesは未対応のため認識されないからanyになる
// v2.9: rはstring
//   * numberのindex typesが認識されるためstringとみなされる

JetBrainsのIDEで型推論が上手く反映されない

稀に、IDE特有の機能を使って判定された型は正しく推論されないことがあります。
その場合はtscの実行結果を確認して、そちらを信じましょう😜

Generic type arguments in JSX elements

HAD BETTER EASY

JSX要素にジェネリクスの型引数を渡せるようになった。
<YourComponent<Props> />のような感じ。

Generic type arguments in generic tagged templates

HAD BETTER EASY

タグ付けテンプレートにジェネリクスが使えるようになった。

export function twice<T>(strs: TemplateStringsArray, ...values: T[]): string {
  return strs.reduce(
    (accum, str, i) => `${accum}${values[i - 1]}${values[i - 1]}${str}`
  );
}

const res1 = twice<string>`I play ${"tennis"} every ${"day"}`;
const res2 = twice<number>`I play ${1} every ${200}`;

console.log(res1);
// -> I play tennistennis every dayday
console.log(res2);
// -> I play 11 every 200200

import types

UNKNOWN EASY

型注釈でimportタイプが使えるようになった。

sub.ts

export declare class Human {
  id: number;
  name: string;
}

main.ts

function getName(human: import("./sub").Human): string {
  return human.name;
}

どういうとき使うのかが分からない..

非モジュールファイルからも宣言のみのクラスをimportできたので..

Relaxing declaration emit visiblity rules

HAD BETTER EASY

TypeScript2.8では、以下のようなケースで.d.tsファイルを作成するとエラーになる。
--declarationオプションを有効にして実行

sub.ts

export interface Result<T> {
  data: T;
}

export const createResult = (): Result<number> => ({ data: 123 });

index.ts

import { createResult } from "./sub";

export const r = createResult();

index.tsResultを明示的にimportするとエラーは消える。

TypeScript2.9では上記のimportなしに.d.tsファイルを作成できるようになった。
import typesの対応によるもので、.d.tsファイル内でも使われている。

import { createResult, Result } from "./sub";

export const r = createResult();

なぜ2.8までではエラーになるのか原因が分からない。。

import typesによって2.9から直感的に型定義ファイルを作成できるようになったのは嬉しいが。。

Support for import.meta

UNKNOWN EASY

TC39でproposalされた新しいmetaプロパティに対応した。
--moduleesnextでないと使えないので注意。

New --resolveJsonModule

SHOULD EASY

--resolveJsonModuleを付けるとjsonファイルをimportできるようになった。
静的jsonであれば補完や型推論も効く。

前提として、moduleResolutionnodeを指定する必要がある。

{
  "name": "sample",
  "version": "1.0.0",
  // 中略
  "devDependencies": {
    "prettier": "^2.0.5",
    "typescript": "^3.9.5"
  }
}
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}
import packageJson from "./package.json";

// 補完も効く
console.log(packageJson.devDependencies)
// -> { prettier: '^2.0.5', typescript: '^3.9.5' }

--pretty output by default

NOT NECESSARY EASY

エラーメッセージを見やすくする--prettyフラグがデフォルトで付与できるようになった。

--prettyフラグはv2.7の変更を参照。

New --declarationMap

HAD BETTER EASY

--declarationMapオプションが追加された。
--declarationと一緒に指定すると、.d.ts.mapファイルが出力される。

.d.ts.mapファイルは .d.tsファイルと.tsファイルのマッピング。

IDEで定義に移動すると通常は.d.tsファイルに移動するが、.d.ts.mapファイルがあれば.tsファイルに直接移動できる。