[英]Why doesn't TypeScript type guard 'in' narrows types to keyof types?
[英]Typescript generics keyof doesn't match type
我有這個接口,它只存儲另一個接口的鍵( modelKey
)和該鍵的值( value
):
interface ValueHolder<T, H extends keyof T> {
modelKey: H;
value: T[H];
}
現在我想存儲來自以下horsePower
的馬力,匹配類型在ValueHolder
中:
interface Car {
id: number;
horsePower?: number;
date: Date;
};
這看起來像這樣:
const test: ValueHolder<Car, keyof Car> = {
modelKey: 'horsePower',
value: 1000,
};
此時不會發生錯誤,它會很好地存儲值。 但您也可以傳遞Date
類型的值:
const test: ValueHolder<Car, keyof Car> = {
modelKey: 'horsePower',
value: new Date(),
};
因為無論出於何種原因,該值都可以接受 model 中提供的所有類型的任何鍵:
(property) ValueHolder<Car, keyof Car>.value: string | number | Date | undefined
如何使接口ValueHolder
的value
鍵只接受undefined | number
undefined | number
,如果你提供的modelKey
horsePower
?
ValueHolder
第二個通用參數H
允許所有鍵,這反過來又導致允許所有值。
您需要稍微修改您的主要實用程序類型,以使非法 state 無法表示。
考慮這個例子:
type Values<T> = T[keyof T]
type ValueHolder<T> = Values<{
[Prop in keyof T]: {
modelKey: Prop;
value: T[Prop]
}
}>
// type Test = {
// modelKey: "id";
// value: number;
// } | {
// modelKey: "horsePower";
// value: number | undefined;
// } | {
// modelKey: "date";
// value: Date;
// } | undefined
type Test = ValueHolder<Car>
interface Car {
id: number;
horsePower?: number;
date: Date;
};
// ok
const test: ValueHolder<Car> = {
modelKey: 'horsePower',
value: 1000,
};
// error
const test2: ValueHolder<Car> = {
modelKey: 'horsePower',
value: new Date(),
};
請參閱type Test
。 ValueHolder
創建所有允許值的聯合。 它遍歷每個鍵並創建此接口 {Prop:{modelKey:P, value:T[P]}}。 然后Values
獲取每個 object 值{modelKey:P, value:T[P]}
並將它們合並。
更新
謝謝,工作正常! 如果我希望
T[Prop]
只能是字符串類型怎么辦? 這也可能嗎?
是的。 有兩種方法可以實現它。 您可以只允許ValueHolder
接收值為字符串的對象。
type ValueHolder<T extends Record<string, string>> = Values<{
[Prop in keyof T]: {
modelKey: Prop;
value: T[Prop]
}
}>
或者,您可以在迭代內部檢查T[Prop]
是否為字符串。
type ValueHolder<T> = Values<{
[Prop in keyof T]: T[Prop] extends string ? {
modelKey: Prop;
value: T[Prop]
} : never
}>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.