関数のタイプ


  • この文章は『実戦反応プログラミング』(李在勝)書の第9章-静的タイプ、およびタイプスクリプト部分をまとめた.
  • 間違いや修正が必要な内容があれば、お知らせください.
  • 関数のタイプ

  • 関数のタイプを定義するには、パラメータタイプと戻りタイプが必要です.
  • function getInfoText(name: string, age: number): string {
      // 매개 변수 타입과 반환 타입 지정
      const nameText = name.substr(0, 10); // 매개변수 name은 문자열 타입이기 때문에 substr 사용 가능
      const ageText = age >= 35 ? 'senior' : 'junior'; // 매개변수 age는 숫자이기 때문에 다른 숫자와 크기 비교 가능
    
      return `name: ${nameText}, age: ${ageText}`;
    }
    const v1: string = getInfoText('mike', 23);
    const v2: string = getInfoText('mike', '23'); // TypeError
    const v3: number = getInfoText('mike', 23); // TypeError
    

    変数を関数タイプとして保存


  • JSでは、関数は1レベルのオブジェクトである(JavaScript Deep Dive-関数(12)編で説明されている).関数は変数に格納できます.

  • 関数の変数タイプを保存するには、矢印記号を使用します.
  • const getInfoText: (name: string, age: number) => void = function (name, age) {
     	// ...
    };

    パラメータの選択


  • 選択パラメータは入力する必要のないパラメータです.

  • パラメータ名の右側に疑問符を入力すると選択パラメータになります.
  • function getInfoText(name: string, age: number, language?: string): string {
      const nameText = name.substr(0, 10);
      const ageText = age >= 35 ? 'senior' : 'junior';
      const languageText = language ? language.substr(0, 10) : '';
    
      return `name: ${nameText}, age: ${ageText}, language: ${languageText}`;
    }
    const v1: string = getInfoText('mike', 23, 'ko');
    const v2: string = getInfoText('mike', 23); // language에 해당하는 인수는 반드시 입력하지는 않아도 괜찮다.
    const v3: number = getInfoText('mike', 23, 123); // Type Error
    function getInfoText(name: string, language?: string, age: number): void {
      // 매개변수 age에서 타입 에러 발생!
    }
    
    

  • 次に、選択したパラメータの右側にある必須パラメータを示します.この場合、コンパイルエラーが発生します.

  • 上記のコードを実装するには、undefinedを使用します.次のようにします.
  • function getInfoText(name: string, language: string | undefined, age: number): void {
      // ...
    }

  • Unionタイプを使用して未定義の内容を入力できます.

  • コンパイルエラーは発生しませんが、読みやすさが悪いです.

  • パラメータの数が多い場合は、非構造化構文を使用して名前付きパラメータとして記述することが望ましい.
  • 残りのパラメータ

    function getInfoText(name: string, ...rest: string[]): void {
      // ...
    }
    
  • の残りのパラメータは配列として格納することができる.
  • このタイプ


  • 関数のthisタイプが定義されていない場合は、anyタイプがデフォルトで使用されます.

  • 前述したように、どんなタイプでもできるだけ使わないほうがいいです.このタイプを定義したほうがいいです.
  • // this타입을 정의하지 않은 코드
    function getParam(this: string, index: number): string {
      const params = this.splt(',');
      if (index < 0 || params.length <= index) return '';
    
      return this.split(',')[index];
    }
  • はわざとspltを間違えた.ただし、このタイプはanyなのでコンパイルエラーは発生しません.
  • // this타입을 정의한 코드
    function getParam(this: string, index: number): string {
      const params = this.splt(','); // 타입 에러 발생
      if (index < 0 || params.length <= index) return '';
    
      return this.split(',')[index];
    }

  • 関数のこのタイプは、次のように最初のパラメータ位置で定義できます.

  • パラメータindexは2番目の位置で定義されます.ただし、このタイプはパラメータではないためindexが最初のパラメータとなる.

  • このタイプが定義されているため、spltエラータイプでタイプエラーが発生します.
  • 元のタイプにメソッドを追加

  • 元のタイプ(JavaScript Deep Dive-データ型(06)で説明)にメソッドを登録するときにインタフェースが使用されます.文字列タイプにメソッドを追加するコードを次に示します.
  • interface String {
      getParam(this: string, index: number): string; // 인터페이스를 이용해 이미 존재하는 문자열 타입에 getParam 메서드를 추가한다.
    }
    
    String.prototype.getParam = getParam; // 문자열의 프로토타입에 작성한 함수를 등록한다.
    console.log('asdf, 1234, ok '.getParam(1)); // 이제 문자열에 등록된 getParam 메서드를 호출할 수 있다.

    関数のリロードかんすうのさいか:複数のタイプを定義するふくすうのたいぷをていぎする


  • JSはダイナミックタイプ言語で、1つの関数には複数のパラメータタイプと戻りタイプがあります.

  • 関数のリロードでは、1つの関数で複数のタイプを定義できます.

  • 次の処理にadd関数を作成するとします.
  • 両方のパラメータが文字列の場合、文字列が返されます.両方のパラメータが数値の場合、数値が返されます.
  • の2つのパラメータは、異なるタイプで入力できません.
  • 以下に、この機能を実現するために関数リロードを使用しないコードを示します.
    function add(x: number | string, y: number | string): number | string {
      if (typeof x === 'number' && typeof y === 'number') return x + y;
      else {
        const result = Number(x) + Number(y);
        return result.toString();
      }
    }
    
    const v1: number = add(1, 2); // Type Error - 모든 매개변수가 숫자이면 반환값도 숫자이지만 Type Error가 발생한다.
    console.log(add(1, '2')); // 두 매개변수의 타입이 달라도 Type Error가 발생하지 않는다.
  • 次の関数リロードを使用して、この条件を満たす関数のタイプを定義します.
  • // 매개변수와 반환 타입의 모든 가능한 조합을 정의한다.
    function add(x: number, y: number): number;
    function add(x: string, y: string): string;
    
    // 실제 구현하는 쪽에서 정의한 타입은 함수 오버로드의 타입 목록에서 제외된다.
    function add(x: number | string, y: number | string): number | string {
      if (typeof x === 'number' && typeof y === 'number') return x + y;
      else {
        const result = Number(x) + Number(y);
        return result.toString();
      }
    }
    
    const v1: number = add(1, 2);
    console.log(add(1, '2')); // TypeError: 두 매개변수의 타입이 다르면 타입에러가 발생한다.

    名前付きパラメータ

    // 우선 모든 매개변수의 이름을 정의한다.
    function getInfoText({
      name,
      age = 15,
      language,
    }: // 앞에 나열된 모든 매개변수에 대한 타입을 정의한다.
    {
      name: string;
      age?: number;
      language?: string;
    }): string {
      const nameText = name.substr(0, 10);
      const ageText = age >= 35 ? 'senior' : 'junior';
    
      return `name: ${nameText}, age: ${ageText}, language: ${language}`;
    }
    
  • ネーミングパラメータのタイプを他のコードで再使用するには、次のコードに示すインタフェースを使用します.
  • interface Param {
      name: String;
      age?: number;
      language?: string;
    }
    
    function getInfoText({ name, age = 15, language }: Param): string {
      const nameText = name.substr(0, 10);
      const ageText = age >= 35 ? 'senior' : 'junior';
    
      return `name: ${nameText}, age: ${ageText}, language: ${language}`;
    }