[TypeScript] 3.4¶
TypeScript3.4のリリース内容まとめ
Faster subsequent builds with the --incremental flag¶
SHOULD EASY
--incremental
オプションを使ってファイル単位でインクリメンタルビルドができるようになった。
ビルド時に作成されるtsconfig.tsbuildinfo
を参照して、必要なビルドを判断する。
以下のファイル構成を含むプロジェクトを例にする。
.
├── main.ts
├── sub.ts
└── tsconfig.json
import { summ } from "./sub";
console.log(summ(39, 39));
export function summ(x: number, y: number) {
return x + y + y;
}
{
"compilerOptions": {
// incremental build
"incremental": true,
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"outDir": "out",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
}
}
npx tsc
を実行するとtsconfig.tsbuildinfo
が生成される。
tsconfig.tsbuildinfo
{
"program": {
"fileInfos": {
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.d.ts": {
"version": "49ff9798f592c8b7e628fd881401e68810c1b3589ecd7a41b32b3c287374cde0",
"signature": "49ff9798f592c8b7e628fd881401e68810c1b3589ecd7a41b32b3c287374cde0"
},
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.es5.d.ts": {
"version": "c8665e66018917580e71792b91022bcaf53fb946fab4aaf8dfb0738ed564db88",
"signature": "c8665e66018917580e71792b91022bcaf53fb946fab4aaf8dfb0738ed564db88"
},
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.dom.d.ts": {
"version": "6994c583b66862deca24d7bbf77297d95b9d3da8160dbd9beef6b847cf7c1376",
"signature": "6994c583b66862deca24d7bbf77297d95b9d3da8160dbd9beef6b847cf7c1376"
},
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.webworker.importscripts.d.ts": {
"version": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b",
"signature": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b"
},
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.scripthost.d.ts": {
"version": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9",
"signature": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9"
},
"c:/users/syoum/work/sandbox/typescript/release-note/sub.ts": {
"version": "a642b6e0940719b7786b24d58aeb960c519b61d650b8bef5cb36f621a0189796",
"signature": "0e2338170381690650d253ab294fb37c7ce39d2716d2d78723676a4b09c93457"
},
"c:/users/syoum/work/sandbox/typescript/release-note/main.ts": {
"version": "dd8f4dcd7b8017a8965f69473ea700aacb154c5423793b174b873a60a7f53004",
"signature": "f761c91419d0a89422a0004ef1a92929dd4d2d5e5c16758654d8b0467d1998c6"
}
},
"options": {
"incremental": true,
"target": 1,
"module": 1,
"sourceMap": true,
"outDir": "C:/Users/syoum/work/sandbox/typescript/release-note/out",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"configFilePath": "C:/Users/syoum/work/sandbox/typescript/release-note/tsconfig.json"
},
"referencedMap": {
"c:/users/syoum/work/sandbox/typescript/release-note/main.ts": [
"c:/users/syoum/work/sandbox/typescript/release-note/sub.ts"
]
},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.d.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.es5.d.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.dom.d.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.webworker.importscripts.d.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/node_modules/typescript/lib/lib.scripthost.d.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/main.ts",
"c:/users/syoum/work/sandbox/typescript/release-note/sub.ts"
]
},
"version": "3.4.5"
}
ファイルに変更が加わっているとversion
が変わる。
関数名や引数名などが変わるとsignature
も変わるが、型変更だけでは変化がなかった。
Higher order type inference from generic functions¶
HAD BETTER EASY
ジェネリクス関数を引数にしてジェネリック関数を返す関数の戻り値(関数)に対して、型推論ができるようになった。
例としてA --(f)--> B
と B --(g)--> C
の合成関数A --(compose)--> C
を考える。
function compose<A, B, C>(f: (arg: A) => B, g: (arg: B) => C): (arg: A) => C {
return (x) => g(f(x));
}
以下のコードにおけるmakeBoxedArray
はT(arg: T) => Box<T[]>
と推論されるべき。
interface Box<T> {
value: T;
}
function makeArray<T>(x: T): T[] {
return [x];
}
function makeBox<U>(value: U): Box<U> {
return { value };
}
const makeBoxedArray = compose(makeArray, makeBox);
だが、TypeScript3.3以前ではそのように推論されない。
TypeScript3.4からは推論される。
Improvements for ReadonlyArray and readonly tuples¶
HAD BETTER EASY
readonlyのArrayをreadonly T[]
のように表現できるようになった。
また、readonlyのTupleを使えるようになった。
readonlyなArray¶
バージョン | 表現 |
---|---|
v3.3以前 | ReadonlyArray<T> |
v3.4 | readonly T[] |
v3.3以前の表現はv3.4でも使える。
readonlyなTuple¶
const fruits: readonly [string, string] = ["apple", "orange"];
fruits[0] = "melon"; // 書き込みはできないのでエラー
Mapped TypesでArrayやTupleを指定したときのreadonly¶
v3.3以前のMapped Typesは、ArrayはTupleに対してreadonly
が有効にならない。
type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};
// number[] とみなされる..
type B = MyReadonly<number[]>;
// [string, boolean] とみなされる..
type C = MyReadonly<[string, boolean]>;
type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};
// readonly number[] とみなされる
type B = MyReadonly<number[]>;
// readonly [string, boolean] とみなされる
type C = MyReadonly<[string, boolean]>;
const assertions¶
HAD BETTER EASY
式にas const
をつけると、値が以下の型である場合に変更不可になる。
- string
- number
- boolean
- array
- tuple
- object
// const fixNumber = 10; と同じ
let fixNumber = 10 as const;
// const fixNums: readonly number[] = [10, 20, 30]; と同じ
const fixNums = [10, 20, 30] as const;
// const fixPair: readonly [number, string] = [100, "hundred"]; と同じ
const fixPair = [100, "hundred"] as const;
// 変更不可なObject
const fixObj = { id: 100, name: "hundred" } as const;
// fixObjNest.inner.id = 777 も不可
const fixObjNest = { inner: { id: 100 } } as const;
<const>
を付けるでもOK。
// const fixNums = [10, 20, 30] as const; と同じ
const fixNums = <const>[10, 20, 30];
Type-checking for globalThis¶
NOT NECESSARY EASY
globalThis
で各環境のグローバルオブジェクトを認識できるようになった。
ブラウザだとwindow
、Node.jsだとglobal
に相当する。
上記の出力は undefined
になる
ちゃんと理由が分かっていない..。
main.js
はグローバルファイルではないからということだろうか..🤔