web-dev-qa-db-ja.com

TypeScriptで、値が文字列であるジェネリックオブジェクトのキーのみを指定するにはどうすればよいですか?

値が文字列であるタイプTのキーで構成されるタイプを作成しようとしています。擬似コードでは、keyof T where T[P] is a stringになります。

これを行うことを考えることができる唯一の方法は、2つのステップです。

// a mapped type that filters out properties that aren't strings via a conditional type
type StringValueKeys<T> = { [P in keyof T]: T[P] extends string ? T[P] : never };

// all keys of the above type
type Key<T> = keyof StringValueKeys<T>;

ただし、TSコンパイラは、条件を使用して値をneverに設定することにより、値が文字列ではないキーを除外したにもかかわらず、Key<T>は単にkeyof Tに等しいと言っています。タイプ。

したがって、これはまだ許可されています。たとえば、次のようになります。

interface Thing {
    id: string;
    price: number;
    other: { stuff: boolean };
}

const key: Key<Thing> = 'other';

他の2つのキーの値は文字列ではないため、keyの唯一の許可された値が実際には"id"ではなく"id" | "price" | "other"である必要がある場合。

TypeScriptプレイグラウンドのコードサンプルへのリンク

4
Aron

Jcalzの答えに代わる別の方法は TypeScriptのBreaking Changes wikiページ :です。

type KeysOfType<TObj, TProp, K extends keyof TObj = keyof TObj> = K extends K ? TObj[K] extends TProp ? K : never : never;
0
cherryblossom