在 TypeScript 中创建类似于 Keyof 的自定义 Valueof 来返回属性值类型的联合
-
在 TypeScript 中使用
valueof
返回属性值类型的联合 -
在 TypeScript 中使用
keyof
和typeof
返回属性值类型的联合 - 使用 TypeScript 中的单个键获取属性值类型
- 在 TypeScript 中使用泛型在编译时检查键值
在本教程中,我们将学习可以用来返回构成属性或对象的类型的不同方法。
我们可以使用三种方法来实现此功能。其中一种方法利用泛型创建名为 valueof
的自定义类型,该类型返回属性的所有联合类型。
第二种方法使用 keyof
和 typeof
类型返回属性的所有联合类型。第三种方法根据需要使用单独的键返回单一类型。
我们还将学习在编译时限制键值条目,如果它们不是同一类型,则通过利用泛型和索引访问类型。
在 TypeScript 中使用 valueof
返回属性值类型的联合
转到 Visual Studio Code 并创建一个名为 typescript-types
的文件夹或使用你喜欢的任何名称。在文件夹下创建一个名为 value-types-using-valueof.ts
的文件。
将以下代码复制并粘贴到 value-types-using-valueof.ts
文件中。
type 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
返回属于传递类型的所有键类型的联合。
我们创建了包含属性 firstName
、lastName
和 doB
的 Customer
对象。前两个属性是字符串类型,最后一个属性是日期类型。
接下来,我们通过将 Customer
传递给 ValueOf<Customer>
泛型类型,创建了一个名为 ValueOfCustomer
的类型。ValueOfCustomer
是我们的新类型,由 Customer
对象中所有关键时间的联合组成。
这意味着 ValueOfCustomer
只能接受类型为字符串和日期的值。
为了验证,我们创建了一个名为 logDetails()
的方法,该方法接受 ValueOfCustomer
类型的参数,并使用它记录 Customer
的 firstName
、lastName
和 doB
。
请注意,如果我们尝试在方法中传递非字符串或日期类型的值,例如数字,我们将收到错误,因为方法参数只接受字符串或数字。
在 TypeScript 中使用 keyof
和 typeof
返回属性值类型的联合
在同一文件夹中,创建一个名为 value-types-using-keyof-and-typeof.ts
的文件。将以下代码复制并粘贴到文件中。
type 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
在上面的代码中,我们定义了包含属性 firstName
、lastName
和 doB
的 Customer
类型。前两个属性是字符串类型,最后一个属性是日期类型。
Customer
对象使用对象中每个属性的具体值进行初始化。名为 customertypes
的类型已创建并分配给 typeof customer[keyof customer]
。
在最后一个例子中,我们提到 keyof
返回所有键类型的联合。这已经应用到我们的 Customer
对象上来做同样的事情。
typeof
将返回从 Customer
对象获取的所有类型,这是在 keyof
的帮助下实现的,如代码所示。
为了验证这一点,我们创建了一个名为 getCustomerInfo()
的方法,该方法接受 customertypes
类型的参数,并使用它来记录 Customer
对象的值。
请注意,如果我们尝试传递非字符串或日期类型的值(例如数字),则在该方法中,我们将收到错误消息,因为新类型不包含类型编号。
使用 TypeScript 中的单个键获取属性值类型
在上面的两个示例中,我们已经介绍了如何检索所有值类型的联合,但在某些情况下,你可能只对一种类型的对象感兴趣。
在此示例中,你将学习如何使用单个键检索对象的单个值类型。
在同一文件夹下,创建一个名为 individual-keys.ts
的文件。将以下代码复制并粘贴到文件中。
type 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 中使用泛型在编译时检查键值
如前面的示例所示,对象由键和值组成。有时我们可能会面临根据其键更改对象值的要求。
在本教程中,我们将学习确保在编译时检查我们传递的值,以确保它们与键的类型相同。
在同一文件夹下创建一个名为 key-value-checking.ts
的文件。将以下代码复制并粘贴到文件中。
type 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
在上面的代码中,我们定义了一个名为 Shipment
的对象,其中包含参数 containerItems
、containerSerial
和 shipmentDate
。
前两个属性是字符串类型,最后一个属性是日期类型。我们定义了一个名为 updateShipment()
的通用方法。
updateShipment()
方法接受两个参数,其中一个是键,第二个是 Shipment
对象的值。
键必须是任何类型的 Shipment
对象键,并使用尖括号参数中的 <K extends keyof Shipment>
进行检查。
由于我们有键 K
,我们可以通过使用 Shipment[K]
索引 Shipment
对象的键来限制传递给该键的值。使用此定义,我们为键输入的每个值都必须与键的类型相同。
请注意,如果你尝试传递未在 Shipment
对象中定义的值,例如数字,编译器会标记问题。
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