オブジェクトと配列から型を推論する

12538 ワード

モチベーション


TypeScriptを使用しているときに、オブジェクトのキーやオブジェクトの値を型として使用する必要があります.
私がこのポストで欲しいものは、簡単な方法でそれをする方法を説明することになっています、そして、それを出版することによって、私は私が忘れるならば、必ず戻る場所があるでしょう😂

オブジェクト


タイプの使用


オブジェクトを使用する場合、オブジェクト内の型を記述するためのインターフェイスまたは型を作成したい場合がありますが、これは素晴らしいですが、このインターフェイスに基づいてオブジェクトを作成する必要がある場合もあります.
interface Fruit {
  name: string;
  price: number;
  available: boolean;
}
const fruit: Fruit = {
  name: "Apple",
  price: 4,
  available: true
}
いくつかの特定のケースに対して、いくつかのコード行に変換できます.
const fruit = {
  name: "Apple",
  price: 4,
  available: true
}
type Fruit = typeof fruit;
このような場合には、初期状態を宣言するように反応を使用する場合、例えば次のようになります.
const initialState = {
  name: "Apple",
  price: 4,
  available: true
}

type Fruit = typeof initialState;

function FruitComponent() {
  const [fruit, setFruit] = useState(initialState);
  {...}
}
この方法は、それを使用して簡単ですFruit 任意のハンドラ関数へのパラメータとして入力します.

キーの使用


Keyof TypeScriptを使用すると、オブジェクトのキーから新しい型が生成されます.例として次のオブジェクトを使いましょう.ここではdocumentation
const fruits = {
  "cod-1": 'Apple',
  "cod-2": 'Pear',
  "cod-3": 'Orange'
}
我々が果物のコードを受け取る機能があると仮定してください、しかし、それは果物の名前を返さなければなりません.
function getFruitName(code: string) {
  const name = fruits[code];
  return name;
}
このスクリプトでは、このエラーが発生します.... type 'string' can't be used to index type { ... } 以来string この場合、実際にオブジェクトのキーと一致することは保証されません"code-1" | "code-2" | "code-3" このため、コードパラメータはより厳密な型を持つ必要がありますkeyof
type Code = keyof typeof fruits;
function getFruitName(code: Code) {
  const name = fruits[code];
  return name;
}
これを行うことができました.type Code = "code-1" | "code-2" | "code-3" , しかし、正直に言うと、このような小さなケースでしか動作しない.

インデックス型


これは私のお気に入りの機能の一つです、いくつかのケースでは、この機能は私たちを助けるようにオブジェクト/インターフェイス/タイプの単一のプロパティのタイプが必要です.ドキュメントhere
次のオブジェクトを仮定します
const fruit = {
  name: "Apple",
  price: 4,
  available: true
}
プロパティ価格の型を知りたい場合は、次のようにします.
// Price expects to be number
type Price = typeof fruit["price"]
四角形の括弧のプロパティを使用して、それを取得するには、これはまた、インターフェイスとタイプのために動作します、私たちはtypeof ここではインターフェイスの例を示します.オブジェクトとしては同じです
interface TFruit {
  name: string,
  price: number,
  available: boolean
};

// Available expects to be boolean
type Available = TFruit["available"];
追加のユースケースがありますIndexed Access Type , しかし、後で説明します.

Valueofはどうですか。


変わったが、可能な使用例は、我々がオブジェクトとしてオブジェクトの値を使用する必要があるということです、buuut valueofは存在しません、心配しないでください、我々にはこれの解決があります、そして、それは全く単純です.
最初の手順は、以前のようにオブジェクトキーの型を取得することです.
const fruits = {
  "cod-1": 'Apple',
  "cod-2": 'Pear',
  "cod-3": 'Orange'
};

type Code = keyof typeof fruits;
ここで、この型を使用し、インデックス付きのアクセス型と組み合わせてオブジェクトの値を型とします
type FruitName = typeof fruits[Code];
このようにして'Apple' | 'Pear' | 'Orange' , かなりクール、右?

アレイ


別のユースケースでは、型として必要な値を配列とすることもできます.
const fruits = ['apple', 'pear', 'orange'];
type Fruits = 'apple' | 'pear' | 'orange';
buuut,no,no,noリストを複製することは本当に正しいことではなく、それを退屈にすることができます.次のようになります.
const fruits = ['apple', 'pera', 'sandia'] as const;
type Fruits = typeof fruits[number];
私たちは少しの間、ここで起こることを理解するために少し立ち止まるべきです.
  • as const これは、配列の値をリテラルとして割り当てるので、fruits[0] 文字列ではありません文字通りではない場合は、この深さに行きたい場合は、PLSのレビューlink
  • fruits[number] ここではindexed-types 再び、[number] 配列のすべての値をUnion型として取得することができます.
  • そして、それは、このヘルプあなたを助ける😎