型推論とは
なぜ調べようと思ったか
・何が省略できて、何が省略できないのか分からない
・各フレームワーク、ライブラリのドキュメントに記載の型指定が分からない
・ReactのFunctionコンポーネントで関数定義をするので関数の型指定の基礎を学びたい
これ以上ないくらいの型指定
アロー関数の場合
例えば以下のような関数があったとき。
//引数の型に応じて戻り値を変える関数
const arrowFunc = (param1, param2) => {
if ((typeof param1 === "number") & (typeof param2 === "number")) {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
この書き方が型がフル指定の型の書き方
ただ、関数定義のときと、引数と戻り値にそれぞれ指定をしていて、重複するので無駄のようです。
type funcType = {
(param1: string | number, param2: string | number): string | number;
};
type paramType = string|number;
//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType = (param1:paramType, param2:paramType) :string|number => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
なので以下いずれかで書くのが良い
type funcType = {
(param1: string | number, param2: string | number): string | number;
};
type paramType = string|number;
//シンボルの方に型指定
const arrowFunc1: funcType = (param1, param2) => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
//関数定義の中で型指定
const arrowFunc2 = (param1:paramType, param2:paramType) :string|number => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
ジェネリック型
型定義を抽象化していくために使う。
事前に必要な型を把握しておくことは困難なので、以下のようにを使うと抽象化できる。
type funcType = {
<T>(param1: T, param2: T): string | number;
};
//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType = (param1, param2): string | number => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
上記だと、引数を持った関数が呼ばれるときに都度型が変わる。
一方、以下の形だと、関数定義をするときに型を定義もしなければならない。
こっちの手法の方がよく見かける気がする
type funcType<T> = {
(param1: T, param2: T): string | number;
};
//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType<string | number> = (param1, param2) => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
省略記法
type funcType<T> = (param1: T, param2: T)=>string | number;
//引数の型に応じて戻り値を変える関数
const arrowFunc: funcType<string | number> = (param1, param2) => {
if (typeof param1 === "number" && typeof param2 === "number") {
return param1 + param2;
} else {
return `${param1}${param2}`;
}
};
参考記事
非常に参考になった記事。
結果的に、上記記事の内容とほぼ重複しているが、備忘録の意味も含めて投稿します。