gpt4 book ai didi

typescript - 推断Typescript中深层嵌套对象的非叶节点类型

转载 作者:行者123 更新时间:2023-12-04 07:53:50 24 4
gpt4 key购买 nike

我一直在玩Inferring types of deeply nested object in Typescript .
原码

const theme = {
button: { margin: { sm: "sm" } },
form: { padding: { sm: "sm1" } }
} as const;

type Theme = typeof theme;

const getStyle = <
K extends keyof Theme,
S extends keyof Theme[K],
M extends keyof Theme[K][S]
>(t: Theme, name: K, style: S, mod: M) => t[name][style][mod];

getStyle(theme, 'button', 'margin', 'sm');
我从原始示例中引入了一种变体 - 在我的代码叶节点中始终具有相同的结构 {sm: string} .
我正在努力修改 getStyle这样客户端只能指定 2 级 key ,并受益于节点结构始终相同的事实;
const getStyleNew = <
K extends keyof Theme,
S extends keyof Theme[K]
>(t: Theme, name: K, style: S) => t[name][style].sm;
不幸的是,这失败了:
Property 'sm' does not exist on type '{ readonly button: { readonly margin: { readonly sm: "sm"; }; }; readonly form: { readonly padding: { readonly sm: "sm"; }; }; }[K][S]'.
有没有办法让编译器相信 sm 在 t[name][style] 上可用在修改后的函数中?
Playground link

最佳答案

一种方法是将样式记录分配给具有 sm 的对象。使用条件输入的属性 Index类型以说明可能缺少 sm .这甚至可以为结果推断出精确的文字类型,而不仅仅是 string .这是一个通用的解决方案,但您也可以使用 Theme而不是 T :

type Index<T, K> = K extends keyof T ? T[K] : undefined;

const getStyleNew = <
T,
K extends keyof T,
S extends keyof T[K]
>(t: T, name: K, style: S) => {
const {sm}: {sm: Index<T[K][S], 'sm'>} = t[name][style]
return sm
};

const test1 = getStyleNew(theme, 'button', 'margin'); // inferred: test1: "sm"
const test2 = getStyleNew(theme, 'form', 'padding'); // inferred: test2: "sm1"
如果您查询没有 sm 的样式记录(例如 header: { fontSize: {} } ),推断的类型将为 undefined :
const test3 = getStyleNew(theme, 'header', 'fontSize'); // inferred: test3: undefined
不确定这是否是最优雅的解决方案,但 extends子句保证键的类型安全,所以它应该是正确的。
TypeScript playground

关于typescript - 推断Typescript中深层嵌套对象的非叶节点类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66806684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com