extends keyof
TypeScript では、一部の型はまたは を使用して定義されますin keyof
。それらの意味を理解しようとしましたが、これまでのところ成功していません。
私が得たのは、keyof
のみで、 の後に指定した型のプロパティ名として存在するすべての名前を可能な値として持つユニオン型を返すというものですkeyof
。
type T = keyof string;
T
したがって は と同等ですstartsWith | endsWith | trim | substring | ...
。
これは正しいです?
extends keyof
さて、その意味について考えてみるとin keyof
、私の直感は次のようになります。
extends keyof
は から派生した任意の型ですT
。つまり、これらすべての値を持ちますが、それ以上の可能性もあります。in keyof
は から値を取得する任意の型ですT
が、必ずしもすべての値を取得する必要はありません (すべて取得することも可能ですが、取得できる値は少ないかもしれません)。
したがって、この視点から、関係extends keyof
を説明すると>=
、関係in keyof
を説明します<=
。これは正しいでしょうか? そうでない場合、何が正しいでしょうか?
ベストアンサー1
任意の型 についてT
、keyof T
は の既知の公開プロパティ名の和集合ですT
。
例:
interface Person {
age: number;
name: string;
}
type PersonKeys = keyof Person; // "age" | "name"
keyof string
したがって、利回りが正しいという仮定はstartsWith | endsWith | trim | ...
正しいです。詳細については、ルックアップタイプのリリースノート。
keyofを拡張する
extends
この場合は、ジェネリックパラメータの型を制限する。 例:
<T, K extends keyof T>
K
したがって、 は のパブリックプロパティ名にしかなれませんT
。これは、 とは異なり、型や継承の拡張とは関係ありません。インターフェースの拡張。
の使用例は、extends keyof
次のようになります。
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person: Person = {
age: 22,
name: "Tobias",
};
// name is a property of person
// --> no error
const name = getProperty(person, "name");
// gender is not a property of person
// --> error
const gender = getProperty(person, "gender");
それ以外ではインデックスの種類に関するドキュメント、私は見つけたこの役に立つ記事。
キーオブ
in
は、インデックス署名文字列、数値、シンボルリテラルの結合で入力したいものです。これと組み合わせることで、keyof
いわゆるマップされたタイプ、元のタイプのすべてのプロパティを再マップします。
の使用例は、in keyof
次のようになります。
type Optional<T> = {
[K in keyof T]?: T[K]
};
const person: Optional<Person> = {
name: "Tobias"
// notice how I do not have to specify an age,
// since age's type is now mapped from 'number' to 'number?'
// and therefore becomes optional
};
それ以外ではマップされた型に関するドキュメント、私は再び発見したこの役に立つ記事。
楽しい事実:
Optional<T>
今作ったタイプは公式の署名と同じものを持っていますPartial<T>
ユーティリティタイプ!