値が文字列であるタイプ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"
である必要がある場合。
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;