blog

TypeScriptラーニング・ノート - インデクサブル型

型をカスタマイズする際、任意の属性シグネチャを許容するインタフェースが必要になる場合があります。 任意の属性は、文字列シグネチャと数値シグネチャの2つの方法で定義できます。 [prop: string...

Dec 9, 2020 · 3 min. read
シェア

カスタム・タイピングを行う場合、任意のプロパティ・シグネチャを許可するインターフェースが必要になることがあります。

一方の属性シグネチャは文字列型で、もう一方の属性シグネチャは数値型です。

string 型の任意の属性

まず、属性シグネチャが文字列の場合は、例えばオブジェクトの属性です:

interface A {
 [prop: string]: number;
}
const obj: A = {
 a: 1,
 b: 3,
};

[prop: string]: number stringはオブジェクトのキーがすべてstring型であることを意味し、numberは属性値の型を指定します。

propは関数の正式なパラメータに似ており、他の名前で呼び出すことができます。

string 型の任意の属性

2つ目のタイプは、属性シグネチャが配列の添え字のような数値型である場合です:

interface B {
 [index: number]: string;
}
const arr: B = ['suukii'];

[index: number]: string B型の配列は任意の数値添え字を持つことができ、配列のメンバは文字列型でなければならないことを意味します。

同様に、indexは関数の正式なパラメータのようなもので、他の識別子を使ってもまったく問題ありません。

同時に2つの任意のプロパティを定義します。

インターフェースはこれら両方の任意の属性を定義することができますが、数値型のシグネチャで指定される値型は、例として文字列型のシグネチャで指定される値型のサブセットでなければならないことに注意してください:

interface C {
 [prop: string]: number;
 [index: number]: string;
}
// Numeric index type 'string' is not assignable to string index type 'number'.

なぜなら、indexは値型として文字列を指定し、propは値型として数値を指定し、文字列は数値のサブセットではないからです。

これを次のように置き換えても、Functionはobjectのサブセットなので、定義は成り立ちます:

interface C {
 [prop: string]: object;
 [index: number]: Function;
}

任意のプロパティと他の型のプロパティの両方を定義します。

もう一つ注意すべき点は、一度属性が定義されると、他のすべての属性の型はその型のサブセットでなければならないということです。

例えば、必須の属性 name とオプションの属性 age、さらに文字列型のその他の属性シグニチャを持つ Person インターフェースが必要だとします。この場合、Person インターフェースは次のように定義します:

interface Person {
 name: string;
 age?: number;
 [prop: string]: string;
}
// Property 'age' of type 'number' is not assignable to string index type 'string'.

[prop: string]: string しかし、この定義は、他の属性の型も文字列でなければならないという指定が存在するため、有効ではありません:

interface Person {
 name: string;
 age?: number;
 [prop: string]: string | number;
}

番号型の属性シグネチャについても同様です:

type MyArray = {
 0: string;
 [index: number]: number;
};
// Property '0' of type 'string' is not assignable to numeric index type 'number'.

しかし、番号型の任意の属性シグネチャは、他の文字列型の属性シグネチャには影響しません:

type Arg = {
 [index: number]: number;
 length: string;
};

上記のように、number型の属性の型はnumberと指定されていますが、length属性はstring型のシグネチャなので、前者の影響を受けません。

Read next

仕事を見つけるために5年間の大きな工場のテストオープン作業もテストされるべきであるが、テストポストを行うために回すことを考えたことがないが、まだiOSに植えられた

そう、私は5年間働き、5つの会社を渡り歩いた人間です。\n\n\n\n\n\nその夜、仕事内容と必要条件を入念にチェックしたところ、技術的なことは一切書かれていないようなので、大丈夫だと思い、引き続き1課をブラッシングし、朝1時に寝たと思います。\n\n\n\n\n\n\n\n2), CVに興味がありますか?はじめに

Dec 9, 2020 · 6 min read

useState 機能的状態管理

Dec 8, 2020 · 2 min read

UIWindowを取得する

Dec 8, 2020 · 2 min read

Golang-context

Dec 8, 2020 · 5 min read