簡體   English   中英

如何使用TypeScript使咖喱吸氣劑函數類型安全?

[英]How make curried getter function typesafe with TypeScript?

我正在嘗試為以下功能編寫類型

function get(prop) {
  return (obj) => obj[prop];
}

最初,我嘗試使用keyof但無法正常使用。 現在我有了這個:

function get<K extends string>(prop: K) {
  return <V, T extends {K: V}>(obj: {K: V}) => obj[prop];
}

但是它給出了錯誤

error TS2536: Type 'K' cannot be used to index type '{ K: V; }'.

由於{K: V}似乎有一個密鑰K所以這似乎有點愚蠢。

是否可以使函數類型安全,以便第一個參數必須是字符串,返回函數的參數必須是具有正確屬性的對象?


更新:感謝您的回答。 但是,兩種解決方案都存在問題。 考慮下面的代碼:

function get<K extends string>(prop: K) {
  return <V, Obj extends Record<K, V>>(obj: Obj): Obj[K] => obj[prop];
}
const a = get("foo")({ foo: 1 });
a + 12;

最后一行導致錯誤,因為打字稿推導出類型{}a 這使函數使用起來非常麻煩,因為必須強制轉換{}

它似乎至少可以每晚進行一次構建:

function get<K extends string>(prop: K) {
  return <V, Obj extends Record<K, V>>(obj: Obj) => obj[prop];
}

AlexG 回答的確實有效。 您也可以不使用Record 這是說明這兩個代碼的代碼。 get使用Record<K, V>get2使用{[x in K]: V}

function get<K extends string>(prop: K) {
  return <V, Obj extends Record<K, V>>(obj: Obj) => obj[prop];
}

function get2<K extends string>(prop: K) {
  return <V, T extends {[x in K]: V}>(obj: T) => obj[prop];
}

const foo = {
  "a": 1,
  "b": 2,
};

console.log(get("b")(foo));
console.log(get2("b")(foo));
// This line should compile fine in recent development versions and
// presumably will work fine in regular releases from 2.2.0 onwards.
// There's a bug in 2.1.x that causes the type inference to bork and 
// cause the compiler to think were adding 1 to a plain object (`{}`).
console.log(get2("b")(foo) + 1);

我知道了上面的內容,然后盡管使用get2我可能只是復制了Record功能,而lo和behold就是這種情況,因為Record的定義是這樣的:

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends string, T> = {
    [P in K]: T;
}

您在更新中提到的類型推斷問題是TypeScript中的一個錯誤,該錯誤已在相對較新的TypeScript版本中修復。 Alex提到了版本2.2.0-dev.20161221。我已經嘗試使用較新的版本,並且也進行了完美的編譯。)大概它將在版本2.2.0中修復。 我不知道有什么解決方案可以解決2.2.0之前的版本中的編譯錯誤,並且不會產生其他負面影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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