我倾向于避免所有条件类型,因为编译器无法很好地推理它们,并且看起来您不需要它们。代替type Foo<T> = T extends U ? F<T> : never
,你可以只是约束 T
, like type Foo<T extends U> = Foo<T>
,这对于编译器来说更简单。
这里的解决方案可能是getStyle()
generic有足够多的类型参数,编译器可以理解每个参数都深入到一个对象中,并且抬头看它的属性。像这样:
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];
这里我们说的是t
属于类型Theme
, that name
属于某种通用类型K
限制于keyof Theme
, that style
属于某种通用类型S
限制于keyof Theme[K]
, 然后mod
属于某种通用类型M
限制于keyof Theme[K][S]
。这允许t[name][style][mod]
编译没有错误,返回类型为getStyle()
被推断为Theme[K][S][M]
,这意味着输出也将是相当强类型的:
const sm = getStyle(theme, "button", "margin", "sm"); // string
const lg = getStyle(theme, "form", "padding", "lg"); // string
好的,希望有帮助。祝你好运!
链接到代码