TypeScript でプロパティ値の型のユニオンを返す Keyof に似たカスタム Valueof を作成する

David Mbochi Njonge 2023年10月8日
  1. TypeScript で valueof を使用してプロパティ値タイプのユニオンを返す
  2. TypeScript で keyoftypeof を使用してプロパティ値タイプのユニオンを返す
  3. TypeScript の個々のキーを使用してプロパティ値タイプを取得する
  4. TypeScript の Generics を使用して、コンパイル時にキー値を確認する
TypeScript でプロパティ値の型のユニオンを返す Keyof に似たカスタム Valueof を作成する

このチュートリアルでは、プロパティまたはオブジェクトを構成する型を返すために使用できるさまざまな方法を学習します。

この機能を実現するために使用できる方法は 3つあります。メソッドの 1つは、ジェネリックを利用して、プロパティのすべてのユニオンタイプを返す valueof という名前のカスタムタイプを作成します。

2 番目のメソッドは、keyof および typeof タイプを使用して、プロパティのすべてのユニオンタイプを返します。3 番目のメソッドは、個々のキーを使用して、必要に応じて単一のタイプを返します。

また、ジェネリックとインデックス付きアクセスタイプを利用して、キー値エントリが同じタイプでない場合は、コンパイル時に制限する方法も学習します。

TypeScript で valueof を使用してプロパティ値タイプのユニオンを返す

ビジュアルスタジオコードに移動し、typescript-types という名前のフォルダーを作成するか、任意の名前を使用します。フォルダの下に value-types-using-valueof.ts という名前のファイルを作成します。

次のコードをコピーして、value-types-using-valueof.ts ファイルに貼り付けます。

TypeScript
 typescriptCopytype ValueOf<T> = T[keyof T];

type Customer = {
    firstName: string,
    lastName: string,
    doB: Date,
}

type ValueOfCustomer = ValueOf<Customer>

let customer: Customer  ={
    firstName: 'john',
    lastName: 'doe',
    doB: new Date(2022,12,6),
}

function logDetails(customerInfo: ValueOfCustomer){
   console.log(customerInfo)
}

logDetails(customer.firstName)
logDetails(customer.lastName)
logDetails(customer.doB)
logDetails(500)// Error - The union does not include type number

まず、汎用タイプ ValueOf<T> を定義し、それを T[keyof T] に割り当てます。T は、プロパティかオブジェクトかに関係なく、任意のタイプを ValueOf に渡すことができることを意味します。

keyof は、渡されたタイプに属するすべてのキータイプの和集合を返します。

プロパティ firstNamelastName、および doB を含む Customer オブジェクトを作成しました。最初の 2つのプロパティは文字列型で、最後のプロパティは日付型です。

次に、CustomerValueOfCustomer ジェネリック型に渡すことにより、ValueOfCustomer という名前の型を作成しました。ValueOfCustomer は、Customer オブジェクトのすべてのキー時間の和集合で構成される新しいタイプです。

つまり、ValueOfCustomer はタイプ文字列と日付の値のみを受け入れることができます。

確認するために、タイプ ValueOfCustomer のパラメーターを受け入れる logDetails() という名前のメソッドを作成し、それを使用して CustomerfirstNamelastName、および doB をログに記録しました。

メソッド内の数値など、文字列または日付タイプではない値を渡そうとすると、メソッド引数は文字列または数値のみを受け入れるため、エラーが発生することに注意してください。

TypeScript で keyoftypeof を使用してプロパティ値タイプのユニオンを返す

同じフォルダに、value-types-using-keyof-and-typeof.ts という名前のファイルを作成します。次のコードをコピーしてファイルに貼り付けます。

TypeScript
 typescriptCopytype Customer = {
    firstName: string,
    lastName: string,
    doB: Date,
}

const customer: Customer  ={
    firstName: 'john',
    lastName: 'doe',
    doB: new Date(2022,12,6),
} as const

type customertypes = typeof customer[keyof Customer]

function getCustomerInfo(theCustomerTypes: customertypes){
    console.log(theCustomerTypes)
}

getCustomerInfo(customer.firstName)
getCustomerInfo(customer.lastName)
getCustomerInfo(customer.doB)
getCustomerInfo(234)//Error - The union does not include type number

上記のコードでは、プロパティ firstNamelastName、および doB を含む Customer タイプを定義しました。最初の 2つのプロパティは文字列型で、最後のプロパティは日付型です。

Customer オブジェクトは、オブジェクトの各プロパティの具体的な値で初期化されます。customertypes という名前のタイプが作成され、typeof customer[keyof customer] に割り当てられました。

最後の例では、keyof がすべてのキータイプの和集合を返すことを説明しました。そして、これは同じことをするために私たちの Customer オブジェクトに適用されました。

typeof は、コードに示されているように、keyof の助けを借りて実現される Customer オブジェクトから取得されたすべてのタイプを返します。

これを確認するために、タイプ customertypes のパラメーターを受け入れる getCustomerInfo() という名前のメソッドを作成し、それを使用して Customer オブジェクトの値をログに記録しました。

文字列型や数値などの日付以外の値を渡そうとすると、新しい型に型番が含まれていないため、エラーが発生することに注意してください。

TypeScript の個々のキーを使用してプロパティ値タイプを取得する

上記の 2つの例では、すべての値タイプの和集合を取得する方法について説明しましたが、場合によっては、1つのタイプのオブジェクトのみに関心がある場合があります。

この例では、個々のキーを使用してオブジェクトの単一の値タイプを取得する方法を学習します。

同じフォルダの下に、individual-keys.ts という名前のファイルを作成します。次のコードをコピーしてファイルに貼り付けます。

TypeScript
 typescriptCopytype Customer = {
    firstName: string,
    lastName: string,
    doB: Date,
}

type date = Customer['doB']

function getDateOfBirth(doB: date): Date{
    return doB;
}

let customer: Customer  ={
    firstName: 'john',
    lastName: 'doe',
    doB: new Date(2022,12,6),
}

getDateOfBirth(customer.doB)
getDateOfBirth(123)//Error - Method accepts a single parameter of type date

この例では、前の例と同じ顧客定義を再利用しています。日付タイプは、Customer['doB'] を使用して顧客定義から doB キーを参照することによって作成されています。

これは、新しい date タイプが Date タイプであることを意味します。getDateOfBirth() には、タイプ date の単一のパラメーターが含まれており、コードに示されているように、日付タイプのみを渡すことができることを確認するために使用されています。

数値など、タイプ date ではない値を渡そうとすると、パラメーターが単一のタイプに制限されているため、エラーが発生します。

TypeScript の Generics を使用して、コンパイル時にキー値を確認する

前の例で見たように、オブジェクトはキーと値で構成されています。キーに基づいてオブジェクトの値を変更する必要がある場合があります。

このチュートリアルでは、渡した値がコンパイル時にチェックされ、キーと同じタイプであることを確認する方法を学習します。

同じフォルダの下に key-value-checking.ts という名前のファイルを作成します。次のコードをコピーしてファイルに貼り付けます。

TypeScript
 typescriptCopytype Shipment = {
    containerItems: string,
    containerSerial: string
    shipmentDate: Date
}

declare function updateShipment<K extends keyof Shipment>(key: K, value: Shipment[K]): void;

updateShipment('containerItems','flowers')
updateShipment('containerSerial','def456');
updateShipment('shipmentDate',new Date(2018,3,14))
updateShipment('shipmentDate',1337)// Error- Shipment object does not contain type number

上記のコードでは、パラメータ containerItemscontainerSerial、および shipmentDate を含む Shipment という名前のオブジェクトを定義しました。

最初の 2つのプロパティは文字列型で、最後のプロパティは日付型です。updateShipment() という名前の汎用メソッドを定義しました。

updateShipment() メソッドは 2つのパラメーターを受け入れます。1つはキーで、もう 1つは Shipment オブジェクトの値です。

キーは任意のタイプの Shipment オブジェクトキーである必要があり、これらは山形文字パラメータの <K extends keyof Shipment> を使用してチェックされます。

キーK があるので、Shipment[K] を使用して Shipment オブジェクトのキーにインデックスを付けることにより、このキーに渡される値を制限できます。この定義では、キーに入力するすべての値は、キーと同じタイプである必要があります。

Shipment オブジェクトで定義されていない値(数値など)を渡そうとすると、コンパイラーが問題にフラグを立てることに注意してください。

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub

関連記事 - TypeScript Type