[英]Why is Typescript coercing my keyof type to a never type and how do I fix it?
對不起,如果這是一個騙局,我是 TypeScript 的新手,並且無法弄清楚看起來相似的問題是否相關,因為他們中的很多人都在做非常復雜的事情。 無論如何,問題是,我有一個相對簡單的設置,TS 正在窒息,因為它強制一種類型never
,我真的不明白它為什么這樣做。 這是設置:
interface BigObject {
foo: {
a?: string
b?: string
}
bar: {
c?: string
d?: string
}
}
const instance: BigObject = {
foo: {
a: "a",
b: "b",
},
bar: {
c: "c",
d: "d",
}
}
function metafunction(bigObjProp: keyof BigObject) {
type LittleObject = BigObject[typeof bigObjProp]
// IDE hints show this ^^ as being correct, i.e. either of the two "sub interfaces"
return function (littleObjProp: keyof LittleObject) { // <== littleObjProp is resolving to never
return function (bigObject: BigObject) {
const littleObject = bigObject[bigObjProp]
return littleObject ? littleObject[littleObjProp] : "fallback value"
}
}
}
const firstClosure = metafunction("foo")
const secondClosure = firstClosure("a") // <== Argument of type "a" is not assignable to type "never"
const value = secondClosure(instance)
我的期望是 value 的value
將是“a”。
我不明白為什么littleObjProp
解析為never
。 我的假設是,由於LittleObject
是從傳遞給參數的類型內置metafunction
,TS會選擇使用任何給定調用其“子接口”。 因此,例如,當我調用metafunction("foo")
,TS 會將LittleObject
設置為{ a?: string; b?: string }
{ a?: string; b?: string }
因此,當我調用firstClosure("a")
,它會說,“啊,是的,'a' 確實是 LittleObject 的有效鍵,繼續”。 然而,它不能這樣做,因為它總是認為keyof LittleObject
意味着never
。
有人可以幫助我理解 1) 為什么這樣做和 2) 如何完成我正在嘗試做的事情? 我意識到這是一個奇怪的設置,但我正在處理一些奇怪的 React 庫,而這正是我目前所處的位置。 請假設我必須保持一個函數的整體結構,該函數返回一個返回一個函數的函數,如示例中所示。 另外,如果您能盡可能簡單地回答我的問題,我將不勝感激,因為我對 TS 有點陌生。 提前致謝!
使metafunction
通用。
正如上面所說,沒有泛型類型。 為了安全起見, firstClosure
只會采用foo
和bar
共有的鍵,但它們沒有共同的鍵,所以never
是唯一可能的參數。 如果您要給它們一個共同的鍵, firstClosure
鍵入firstClosure
以接受該鍵。
interface BigObject {
foo: {
a?: string
b?: string
f?: string // Added
}
bar: {
c?: string
d?: string
f?: string // Added
}
}
const instance: BigObject = {
foo: {
a: "a",
b: "b",
f: "f",
},
bar: {
c: "c",
d: "d",
f: "f",
}
}
const secondClosure = firstClosure("f") // "f" is the only valid value
通過添加泛型,您可以說服 Typescript 將類型信息保留為metafunction
和firstClosure
每個的屬性,這為您的閉包提供您正在尋找的類型。
function metafunction<T extends keyof BigObject>(bigObjProp: T) {
type LittleObject = BigObject[T]
return function (littleObjProp: keyof LittleObject) {
return function (bigObject: BigObject) {
const littleObject = bigObject[bigObjProp]
return littleObject[littleObjProp] ?? "fallback value"
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.