[英]type argument inference for interfaces and types without functions
在此示例中,我希望表達式itemKV1
中的property
屬性約束自身,因此當property
為age
時, value
只能是number
類型。
關於如何做這樣的事情的任何想法?
我知道如何在函數中使用 generics 執行此操作,因為它提供type argument inference
,如此處所述。
問題是我無法推斷property
來約束value
。 我想不出用接口或類型來做到這一點的方法。
interface Item {
id: string;
name: string;
age: number;
}
// Where can I add a generic for `keyof T`?
type KV<T> = { property: keyof T; value: T[keyof T] };
// I want value to be of type `number`, not `string | number`
// this should show an error, but doesn't.
const itemKV1: KV<Item> = {
property: "age",
value: "not a number!"
};
// This should not error and doesn't.
const itemKV2: KV<Item> = {
property: "age",
value: 82
};
通常不可能同時推斷和約束變量的類型。 您要么在注解中指定類型,要么讓編譯器根據賦值推斷它。
但是,對於您的特定情況,還有另一種解決方案可以在您想要的作業上出錯。 您可以將所有可能的property
/ value
組合的並集生成為並集。
interface Item {
id: string;
name: string;
age: number;
}
// Where can I add a generic for `keyof T`?
type KV<T> = {
[P in keyof T]: { property: P; value: T[P] };
}[keyof T]
// KV<Item> =
// | { property: "id"; value: string; }
// | { property: "name"; value: string; }
// | { property: "age"; value: number; }
// Error value is not numebr
const itemKV1: KV<Item> = {
property: "age",
value: "not a number!"
};
// ok
const itemKV2: KV<Item> = {
property: "age",
value: 82
};
注意: itemKV1.value
仍然是string | number
類型。 string | number
,除非您根據property
字段縮小范圍。 如果您希望變量的最終類型基於賦值但受到約束,您將需要 function:
function property<T>() {
return function <TKV extends KV<T>>(o: TKV) {
return o
}
}
// ok
// const itemKV2: {
// property: "age";
// value: number;
// }
const itemKV2 = property<Item>()({
property: "age",
value: 82
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.