[英]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.