目次
- TypeScriptのリリースについて
- TypeScriptは1.xしか知らないと戦力外
- never型
- Numeric Literal Types
- readonly
- String Enum
- Numeric separators
- Improved control over mapped type modifiers
- readonly tuples
- Stricter Generators
- Nullish Coalescing
- Optional Chaining
- Uncalled Function Checks
- ECMAScript Private Fields
- export * as
- Short-Circuiting Assignment Operators
- 補足
TypeScriptのリリースについて
TypeScriptは2012年10月1日にマイクロソフトによってリリースされた。
JavaScriptをベースに省略も可能な静的型付けとクラスベースオブジェクト指向を加えた厳密なスーパーセットとなっていて使い勝手が良いため、現在でも多くの開発現場で使用されている。
TypeScriptの2.0がリリースされたのは2016年9月22日でその後も3.0, 4.0がリリースされて2021年1月12日現在の最新版はバージョン4.1.3となっている。
TypeScriptは1.xしか知らないと戦力外
TypeScriptはバージョンがアップデートされるたびに新機能が導入されて、1.xの古いバージョンとは別物となっている。
この記事では1.xの静的型付けとクラスベースオブジェクト指向などの基本機能しか知らない人が必ず知っておくべきバージョン2以降の新機能をまとめた。
これらを習得していないのであればTypeScriptができると安易に言わないほうが賢明。
TypeScriptの開発環境はParcelかwebpackなどをnpmでインストールすれば簡単に用意できる。
never型
TypeScript 2.0 から導入
any型やvoid型などは知っていてもnever型は知らない人は結構多い。
返り値が何もない場合は:voidだがthrow new Errorやループで返り値が発生しない場合はnever型を使う。
function error(message: string): never {
throw new Error(message);
}
Numeric Literal Types
TypeScript 2.0 から導入
String Literal Typesはバージョン1.8から存在したが、NumericやBooleanなどString以降はバージョン2以降に遅れて導入された。
function dice(): 1 | 2 | 3 {
return (Math.floor(Math.random() * 3) + 1) as 1 | 2 | 3
}
const result = dice()
console.log(result)
// 1 or 2 or 3
readonly
TypeScript 2.0 から導入
変数を読み込み専用にする。
オブジェクト、配列、classの値を変更不可にできる。
interface Point {
readonly x: number;
readonly y: number;
}
var p: Point = { x: 1, y: 2 };
p.x = 3; // Error, p.x is read-only
String Enum
CやJavaなどにあるString EnumがTypeScriptに導入された。
…が、TypeScriptがJavaScriptのスーパーセットであることや、型が安全でないなどの理由により使用されないことが多い。
enum Colors {
Red = 'RED',
Green = 'GREEN',
Blue = 'BLUE'
}
console.log(Colors)
/*
{
Red: "RED",
Green: "GREEN",
Blue: "BLUE"
}
*/
Numeric separators
アンダースコアを数値セパレーターをして使用できる。
数値の桁が多い場合は_で分けれおけば桁数の間違えを防止しやすくなる。
const million:number = 1_000_000
console.log(million)
// => 1000000
Improved control over mapped type modifiers
-readonlyのように修飾子に-を付けると解除できる。
type Foo<T> = { -readonly [P in keyof T]-?: T[P] }
readonly tuples
配列のタプルでreadonlyが使えるようになった。
function foo(arr: readonly string[]) {
arr.slice(); // okay
arr.push("hello!"); // error!
}
Stricter Generators
厳密なチェックがイテレータとジェネレータでもできるようになった。
function* count() {
let i = 1
while (true) {
if (yield i++) {
break
}
}
return 4649
}
const iter = count()
let curr = iter.next()
while (!curr.done) {
console.log(curr.value)
curr = iter.next(curr.value === 3)
}
console.log(curr.value)
/* console結果
1
2
3
4639
*/
/**
* - yields numbers
* - returns strings
* - can be passed in booleans
*/
function* count():Generator<number, string, boolean> {
let i = 1
while (true) {
if (yield i++) {
break
}
}
return 4649 // stringではなくnumberなのでエラー
}
const iter = count()
let curr = iter.next()
while (!curr.done) {
console.log(curr.value)
curr = iter.next(curr.value === 3)
}
console.log(curr.value)
Nullish Coalescing
変数がnullかundefinedのときに後続の処理を行う仕組み。
const foo:any = undefined
const bar = ():void => console.log('Hello!')
let a = foo !== null && foo !== undefined ? foo : bar()
let b = foo ?? bar()
// a と b は同じ結果
console.log(a) // => 'Hello!'
console.log(b) // => 'Hello!'
Optional Chaining
変数がnullかundefinedのときに後続の処理を行わない仕組み。
例えばfoo.toUpperCase()はfooの変数がundefinedかnullだとエラーになってしまうが、foo?.toUpperCase()だとエラーにならなくなる。
const foo:any = undefined
const r1 = foo?.trim()
console.log(r1)
// => undefined
const bar:any = undefined
const r2 = bar.trim()
console.log(r2)
// => エラーになる
Uncalled Function Checks
呼ばれていないFunctionをチェックする。
interface User {
isAdministrator(): boolean;
}
function foo(user: User) {
if (user.isAdministrator) {
// 処理
}
}
ECMAScript Private Fields
privateを#で記述できるようになった。
#だとブラケット構文の場合はundefinedとなるため完全に読み取り不可となる。
// privateを使用する場合
class Person {
private name: string
constructor(name: string) {
this.name = name
}
hello() {
console.log(`Hello, ${this.name}!`)
}
}
const ken = new Person('Ken')
ken.hello()
// => Hello, Ken!
console.log(ken['name'])
// => Ken
console.log(ken.name)
// Error!
// #を使用する場合
class Person {
#name: string
constructor(name: string) {
this.#name = name
}
hello() {
console.log(`Hello, ${this.#name}!`)
}
}
const ken = new Person('Ken')
ken.hello()
// => Hello, Ken!
console.log(ken['#name'])
// undefined
console.log(ken.#name)
// Error!
export * as
ECMAScript 2020からexport * as が使えるようになった。
export * as utilities from "./utilities.js";
Short-Circuiting Assignment Operators
// これを
a = a && b;
a = a || b;
a = a ?? b;
// このように書ける
a &&= b;
a ||= b;
a ??= b;
let a = 0
const b = 2
// a = a || b と同じ
a ||= b
console.log(a)
// 2
補足
この記事に書かれているのはTypeScript バージョン2以降で導入された新機能のごく一部にすぎないので、さらに詳しく知りたい方は公式サイトをご参照下さい。