LoginSignup
177
185

More than 1 year has passed since last update.

【TypeScript】関数の型を書く方法忘れるのでまとめ

Last updated at Posted at 2022-01-23

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 = ~~ となり = が必要

以上となります。
お読み頂き有難うございました。

177
185
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
177
185