TypeScriptで関数を書くときに色々な書き方があり、よく忘れてしまうので個人的な備忘録として記事にいたします。
関数の書き方が色々ありすぎて面倒臭い
1. Class内メソッドのケース
定型文
functionName(args: argsType): returnType {
// run process
}
使用例
export class Personal {
constructor(private _firstName: string, private _lastName: string) {}
sayHello(name: string): string {
return `Hello! ${name}`;
}
}
2. 関数の型だけを定義するケース
続いては、関数の型だけを定義するケースです。
多くのパターンがありますので、個別に見てみます。
2-1. Class内に型を定義するケース
現在非推奨ですが、Nuxt.js の nuxt-property-decorator
などを使用するケースなどです。
定型文
functionType!: (args: argsType) => returnType;
使用例
export default class Index extends Vue {
fetchFormData!: (args: string) => Promise<void>;
async init() {
await this.fetchFormData('hoge');
}
async created() {
await this.init();
}
}
2-2.抽象クラスとして定義するケース
定型文
export abstract class Personal {
abstract functionType: (args: argsType) => returnType;
}
2-3. typeで型を定義するケース
定型文
type FunctionName = (args: argsType) => returnType;
const functionName: FunctionName = (args) => {
// run process
}
使用例
type Calculate = (price: number, tax: number) => number;
const calculate: Calculate = (price, tax) => {
return price * tax;
};
const totalPrice = calculate(100, 10);
2-4. interfaceで型を定義するケース
定型文
interface FunctionType {
(args: argsType): returnType;
};
const functionName: FunctionType = (args) => {
return args;
};
使用例
interface Calculate {
(price: number, tax: number): number;
}
const calculate: Calculate = (price, tax) => {
return price * tax;
};
const totalPrice = calculate(100, 10);
JavaScriptはオブジェクト内に関数が持てるので、
以下のようにすることもできます。
(著者は使用したことありませんが)
// 型の定義:関数が複数存在するケース
interface SomeFunction {
functionName1(): returnType;
functionName2(args: argsType): returnType;
}
// 型からオブジェクトを作る
const someFunction: SomeFunction {
functionName1() {
return 100;
};
functionName2(args) {
console.log('hoge')
};
}
// オブジェクト内の関数を使用
someFunction.functionName1();
3. 関数宣言と同時に型を定義するケース
先ほどは、先に型を定義してから関数の宣言をしていましたが、
こちらは、関数宣言と同時に型を定義するケースです。
3-1. パターン1
定型文
const functionName: (args: argsType) => returnType = (args) => {
// run process
};
使用例
const calculate: (price: number, tax: number) => number = (price, tax) => {
return price * tax;
};
calculate(100, 10);
こちらは可読性が悪いので、少し解説を加えます。
functionNameから後の、 : () => returnType までは型
です。
// ここまでが型の定義
const functionName: (args: argsType) => returnType
そこから後の、= () => が実装
になります。
// この部分が実装
= (argsValue) => {
// run process
};
2022/01/27追記
※ただし、返り値の型を型推論する場合は以下の形になる
const calculate = (price: number, tax: number) => {
return price * tax;
};
calculate(100, 10);
3-2. パターン2
※2022/02/21追記
こちらのパターンが漏れていたため、追記致します。
(ご指摘頂き有難うございます)
const calculate = (price: number, tax: number): number => {
return price * tax;
};
まとめ
- 関数の型は色々なケースと書き方が存在する
- 「関数宣言時」は基本的に
:
に続く記述が型 - 「関数宣言時」は基本的に
=>
に続く記述が実装 -
関数宣言と同時に型を宣言すると、
= =>
が2回登場するので、非常に可読性が悪い- ただし、3-2. パターン2だと短く記載できる
- 「クラス内」での関数宣言時は、
functionName() ~~
となり、=
が不要 - 「クラス外」での関数宣言時は、
functionName: FunctionType = ~~
となり=
が必要
以上となります。
お読み頂き有難うございました。