如何在从对象中提取时保留类型,但考虑到未定义的键



考虑下面的代码,代码const foundKey = classDict[key]的类型应该是object | undefined,因为可以输入不属于dict对象的键(例如dict['bar'](。

然而,我似乎不知道如何做到这一点。有人知道如何做到这一点吗?

功能

function classMatcher<
K extends keyof T,
T extends baseClassDict_T
>(keys: K[], classDict: T): T[K] | undefined {
for (let key of keys) {
const foundKey = classDict[key]; // <---- Type = object, should equal object | undefined
if (foundKey !== undefined) return foundKey;
}
return undefined;
}
type baseClassDict_T = {
[key: string]: {
component: (prop: any) => JSX.Element;
};
};

用法

const keys = ['foo', 'bar'];
const dict = {
foo: {
component: //misc...
}
}
classMatcher(keys, dict)

我认为您没有抓住要点。如果所有内容都正确键入,则不可能计算为undefined。让我解释一下。

来自此类型:

type baseClassDict_T = {
[key: string]: {
component: (props: any) => JSX.Element;
}
}

此类型的对象的所有key将始终是一个字符串。

接下来,重要部分:

function classMatcher<K extends keyof T, T extends baseClassDict_T>(keys: K[], classDict: T)

泛型K extends keyof T基本上说K将始终是一个字符串,并且这个字符串将始终是来自T的属性之一。

这意味着参数keys永远不能接受任何不是参数classDIct属性的字符串。意思是这个代码:

classMatcher(['a', 'b', 'c'], {
a: { component: <></> },
c: { component: <></> }
});

总是会有打字错误,并且永远不会通过类型检查;b";在classDict对象中不存在。

因此,该行:

const foundKey = classDict[key];

永远不会计算为未定义。

请看这个操场上正在进行的解释。

相关内容

最新更新