gpt4 book ai didi

typescript - 强制泛型方法参数是传入的完整联合

转载 作者:行者123 更新时间:2023-12-05 05:29:55 26 4
gpt4 key购买 nike

试图强制具有泛型参数的方法具有联合类型。问题是 TS 可以执行此方法以仅满足并集,而不是实际上 并集。我可能在这里误用了满足术语,但我希望我的观点在下面的示例中得到清楚的表达。

interface IFoo<TArg> {
myMethod(arg: TArg): void;
}

class Foo implements IFoo<string | number> {
// TS doesn't complain because string satisfies string | number.
// How can I make TypeScript force arg to explicitly be string | number?
myMethod(arg: string): void {
//
}
}


class Foo2 implements IFoo<string | number> {
// What I want TS to enforce:
myMethod(arg: string | number): void {
//
}
}

我弄乱了元组并尝试寻找可以解决此问题的辅助类型,但无济于事。

编辑: Playground 链接:https://tsplay.dev/wOx5EN

最佳答案

你遇到了一个事实 method parameters are bivariant在 typescript 中。这意味着您可以在实现接口(interface)时缩小方法参数的类型,例如缩小 string | number只是string .这不是类型安全的(如果有人用数字参数调用 myMethod() 怎么办?),但它对于一些重要的用例很方便(您还可以查看 this FAQ entry 了解原因)。

现在,这曾经是所有 函数的情况,但是自从the --strictFunctionTypes compiler flag引入后,您可以将双方差检查限制为仅方法,而其他函数类型将以安全的逆变 方式检查其参数。 (您可以查看 Difference between Variance, Covariance, Contravariance and Bivariance in TypeScript 了解更多信息。)

这意味着您可以回避这个问题的一种方法是声明 myMethod()IFoo<TArg>作为具有 function type 的属性而不是方法类型:

interface IFoo<TArg> {
myMethod: (arg: TArg) => void;
}

看起来这会强制实现类来生成 myMethod实例属性而不是方法,但事实并非如此。所以这很好用:

class Foo2 implements IFoo<string | number> {
myMethod(arg: string | number): void { // okay
//
}
}

但即使您将其实现为方法,现在也会根据接口(interface)函数属性参数对参数进行逆变检查:

class Foo implements IFoo<string | number> {
myMethod(arg: string): void { // error!!!
//
}
}

然后您得到了您要查找的错误。

Playground link to code

关于typescript - 强制泛型方法参数是传入的完整联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74818496/

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