簡體   English   中英

沒有函數的接口和類型的類型參數推斷

[英]type argument inference for interfaces and types without functions

在此示例中,我希望表達式itemKV1中的property屬性約束自身,因此當propertyage時, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM