【发布时间】:2021-12-21 15:10:09
【问题描述】:
我有一个用例,我想将一组过滤器定义为一个对象。我想知道究竟有哪些过滤器并为其自动完成,但在过滤器的通用处理中,只要它的值符合某些类型,它就可以是任何键。我想使用泛型和扩展,这在一定程度上有效,但在某些情况下,它并没有像我期望的那样根据它扩展的类型进行统一。这是我尝试过的以及出了什么问题的简化示例:
type Foo = { [key: string]: boolean | string[] }
class Bar<F extends Foo> {
constructor(public arg: F) {}
}
const bar = new Bar({ foo: false, bar: [] })
// Reported as always being false.
console.log(bar.arg.foo)
for (const n of bar.arg.bar) {
// Property 'includes' does not exist on type 'never'. ts(2339)
n.includes("x")
}
我希望它推断出boolean 而不是false(对于foo),以及string[] 而不是never[](对于bar)。我假设 extends 并没有像我预期的那样统一类型。有没有办法在 TypeScript 中实现这一点?这意味着我将充分了解Bar 的实例具有foo 和bar 属性,但在类本身内部,它只知道泛型类型(例如,某个对象,而不是知道它的特定键) .
【问题讨论】:
-
TypeScript 需要符合 ms/TS#10676 的窄类型(无论如何对于
boolean)。您可以强制编译器计算F的扩展版本,例如this,但使用起来有些不符合人体工程学,至少对于Bar的实现者而言。这是否满足您的需求,或者您是否正在寻找其他东西(如果是,您能否详细说明)? -
还有this approach 描述了
Bar类构造函数的所需类型,然后只是断言给定的类构造函数值可以分配给它。对于Bar的用户来说,这个可能更好,但对于实施者来说,它又不符合人体工程学。 -
@jcalz 我有点希望这是一个足够常见的用例,不必像那样拼写出来。但是,它确实运作良好,所以如果您提出它作为答案,我会接受它。谢谢!
标签: typescript types typescript-generics