www.oreilly.com
Declaring And Invoking Functions
Optional and Default Parameters
Rest Parameters
- 語彙
- fixed-arity
- variadic
- 任意長引数の
- 【補】引数の数に応じて monadic, diadic, triadic, ... と呼んだりする
- 固定長ではなく任意長引数にしたいことがある
arguments
は型安全じゃないのでやめよう
function sum() {
return Array
.from(arguments)
.reduce((total, n) => total + n, 0)
}
sum(1, 2, 3)
function sum(...numbers: number[]) {
return numbers
.reduce((total, n) => total + n, 0)
}
sum(1, 2, 3)
function sum(...numbers: [number, ...number[]]) {
return numbers
.reduce((total, n) => total + n, 0)
}
sum()
sum(1)
sum(1,2)
call, apply, and bind
TSC Flag: strictBindCallApply
function withUnit(num: number, unit: string) {
return `${num} ${unit}`;
}
withUnit(10, 'cm');
withUnit.call(null, 10, 20);
withUnit.call(null, 10, 'cm');
withUnit.apply(null, [10, 20]);
withUnit.apply(null, [10, 'cm']);
withUnit.bind(null, 10, 20)();
withUnit.bind(null, 10, 'cm')();
Typing this
TSC Flag: noImplicitThis
const x = {
a() {
return this
}
}
console.log(x.a())
const a = x.a
console.log(a())
console.log(a.call(x))
function month(this: Date) {
return this.getMonth()
}
month();
month.call(new Date);
Generator Functions
function* createFibonacciGenerator() {
let a = 0
let b = 1
for (; ;) {
yield a;
[a, b] = [b, a + b]
}
}
const fibonacciGenerator = createFibonacciGenerator()
console.log(fibonacciGenerator.next())
console.log(fibonacciGenerator.next())
console.log(fibonacciGenerator.next())
Iterators
- Generatorの異なる側面
- Generatorは値のストリームを生成する方法
- Iteratorはその値を消費する方法
- iterable
Symbol.iterator
プロパティを持つ任意のオブジェクト
- iterator
next
メソッドをもつ任意のオブジェクト
value
プロパティとdone
プロパティを持つオブジェクトを返す
- 先の例でいう
IteratorResult<number, void>
- ジェネレータ関数の戻り値がこれ
- 先の例でいう
Generator<number, void, unknown>
const xs = [1, 2, 3];
const iteratorCreater = xs[Symbol.iterator]
const iterator = iteratorCreater()
const result = iterator.next()
TSC Flag: downlevelIteration
- ES2015よりも古い環境でカスタムイテレータを動かすためのフラグ
- 無効にすることでバンドルサイズを抑えられる
Call Signatures
const add = function(a: number, b: number) {
return a + b
}
let add: (apple: number, banana: number) => number;
add = function(a: number, b: number) {
return a + b
}
Contextual Typing
function times(
f: (index: number) => void,
n: number
) {
for (let i = 0; i < n; i++) {
f(i)
}
}
times(n => console.log(n), 4)
times
が f: (index: number) => void
を要求しているので、コールバックが(n: number) => void
に推論される
- インラインで定義しないとこの推論は行われない
function times(
f: (index: number) => void,
n: number
) {
for (let i = 0; i < n; i++) {
f(i)
}
}
const log = n => console.log(n)
times(log, 4)
Overloaded Function Types
type Reservation = object
type Reserve = (from: Date, to: Date, destination: string) => Reservation
type Reservation = object
type Reserve = {
(from: Date, to: Date, destination: string): Reservation
}
type Reservation = object
type Reserve = {
(from: Date, to: Date, destination: string): Reservation
(from: Date, destination: string): Reservation
}
const reserve: Reserve = (
from: Date,
toOrDestination: Date | string,
destination?: string
) => {
return {}
}
function createElement(tag: 'a'): HTMLAnchorElement
function createElement(tag: 'canvas'): HTMLCanvasElement
function createElement(tag: 'table'): HTMLTableElement
function createElement(tag: 'a' | 'canvas' | 'table') {
if (tag === 'a') return new HTMLAnchorElement
if (tag === 'canvas') return new HTMLCanvasElement
if (tag === 'table') return new HTMLTableElement
const n: never = tag
return n
}
const anchor = createElement('a')
const canvas = createElement('canvas')
const table = createElement('table')
Column: Keeping Overload Signatures Specific
const reserve: Reserve = (
from: Date,
toOrDestination: any,
destination?: string
) => {
return {}
}
英語