TypeScript の「keyof typeof」とはどういう意味ですか? 質問する

TypeScript の「keyof typeof」とはどういう意味ですか? 質問する

keyof typeofTypeScriptで何を意味するのか教えてください

例:

enum ColorsEnum {
    white = '#ffffff',
    black = '#000000',
}

type Colors = keyof typeof ColorsEnum;

最後の行は次の行と同等です。

type Colors = "white" | "black"

しかし、それはどのように機能するのでしょうか?

typeof ColorsEnum次のようなものを返して"Object"keyof "Object"何も面白いことはしないだろうと予想していました。しかし、明らかに私は間違っています。

ベストアンサー1

keyof typeofTypeScript での使用法を理解するには、まずリテラル型リテラル型の和集合が何であるかを理解する必要があります。そこで、まずこれらの概念を説明し、次にkeyofと をtypeof個別に詳しく説明します。その後、 に戻ってenum質問の内容に答えます。長い回答ですが、例は理解しやすいです。


リテラル型

TypeScript のリテラル型はstring、 、number、または のより具体的な型ですboolean。たとえば、"Hello World"は ですstringが、 はstringではありません"Hello World""Hello World"は 型のより具体的な型なのでstring、リテラル型です。

リテラル型は次のように宣言できます。

type Greeting = "Hello"

つまり、次のコードに示すように、型のオブジェクトには値Greetingのみを設定でき、他の値や他の型の他の値を設定することはできません。string"Hello"string

let greeting: Greeting
greeting = "Hello" // OK
greeting = "Hi"    // Error: Type '"Hi"' is not assignable to type '"Hello"'

リテラル型はそれ自体では役に立ちませんが、ユニオン型、型エイリアス、型ガードと組み合わせると強力になります。

以下はリテラル型の結合の例です。

type Greeting = "Hello" | "Hi" | "Welcome"

これで、 型のオブジェクトは、、、 のGreetingいずれかの値を持つことができます。"Hello""Hi""Welcome"

let greeting: Greeting
greeting = "Hello"       // OK
greeting = "Hi"          // OK
greeting = "Welcome"     // OK
greeting = "GoodEvening" // Error: Type '"GoodEvening"' is not assignable to type 'Greeting'

keyofのみ

keyof何らかの型は、リテラル型の和集合でTある新しい型を提供し、これらのリテラル型は のプロパティの名前です。結果の型は文字列のサブタイプです。T

たとえば、次のことを考慮してくださいinterface

interface Person {
    name: string
    age: number
    location: string
}

keyof型に対して演算子を使用すると、Person次のコードに示すように新しい型が生成されます。

type SomeNewType = keyof Person

これは、型 のプロパティから作成されたSomeNewTypeリテラル型 ( ) の結合です。"name" | "age" | "location"Person

これで、次のタイプのオブジェクトを作成できますSomeNewType:

let newTypeObject: SomeNewType
newTypeObject = "name"           // OK
newTypeObject = "age"            // OK
newTypeObject = "location"       // OK
newTypeObject = "anyOtherValue"  // Error...

keyof typeof一緒にオブジェクトに

すでにご存知かもしれませんが、typeof演算子はオブジェクトの型を示します。上記のインターフェースの例では、型はすでにわかっていたので、 type に対して演算子Personを使用するだけで済みました。keyofPerson

しかし、オブジェクトの型がわからない場合、または次のように値だけがあってその値の型がわからない場合はどうすればよいでしょうか?

const bmw = { name: "BMW", power: "1000hp" }

ここは一緒に使うところですkeyof typeof

次のtypeof bmwようなタイプが提供されます:{ name: string, power: string }

そして、keyof演算子は次のコードに示すようにリテラル型のユニオンを提供します。

type CarLiteralType = keyof typeof bmw

let carPropertyLiteral: CarLiteralType
carPropertyLiteral = "name"       // OK
carPropertyLiteral = "power"      // OK
carPropertyLiteral = "anyOther"   // Error...

keyof typeofenum

TypeScript では、定数の型安全性を確保するために、コンパイル時には列挙型が型として使用されますが、実行時にはオブジェクトとして扱われます。これは、TypeScript コードが JavaScript にコンパイルされると、列挙型がプレーン オブジェクトに変換されるためです。したがって、上記のオブジェクトの説明はここでも当てはまります。質問で OP が示した例は次のとおりです。

enum ColorsEnum {
    white = '#ffffff',
    black = '#000000',
}

ここでは、ColorsEnum実行時に型としてではなくオブジェクトとして存在します。そのため、keyof typeof次のコードに示すように、演算子を一緒に呼び出す必要があります。

type Colors = keyof typeof ColorsEnum

let colorLiteral: Colors
colorLiteral = "white"  // OK
colorLiteral = "black"  // OK
colorLiteral = "red"    // Error...

おすすめ記事