jsa*_*mol 7 generics typescript
我正在寻找一种方法来使我的代码更加类型安全,并希望在将它们传递给泛型函数时定义一些类型之间的密切关系。
例如,对于给定的类型集:
interface FooParam {}
interface FooReturn {}
interface BarParam {}
interface BarReturn {}
Run Code Online (Sandbox Code Playgroud)
以及以下功能:
function action<T, R>(foo: T): R
Run Code Online (Sandbox Code Playgroud)
我想紧密结合FooParam与FooReturn和BarParam用BarReturn的,所以编译器允许只有在对相关类型的作为通过调用T和R返回一个错误,否则。
action<FooParam, FooReturn>(...) // bound types, OK
action<BarParam, BarReturn>(...) // bound types, OK
action<FooParam, BarReturn>(...) // types are not bound, ERROR
action<FooParam, string>(...) // types are not bound, ERROR
Run Code Online (Sandbox Code Playgroud)
我实际上已经通过定义两个基本接口来实现上述目标,这些接口稍后将用作泛型类型的约束:
interface Param {}
interface Return<T extends Param>{
_typeGuard?: keyof T
}
interface FooParam extends Param {}
interface FooReturn extends Return<FooParam> {}
interface BarParam extends Param {}
interface BarReturn extends Return<BarParam> {}
function action<T extends Param, R extends Return<T>>(foo: T): R
Run Code Online (Sandbox Code Playgroud)
然而,这似乎更像是一种变通方法而不是一个干净的解决方案,特别是考虑到该_typeGuard?: keyof T领域,它仅存在于T实际重要并且被检查而不是被忽略的领域。另一个缺点是每种类型都必须扩展我的自定义接口之一,这有时是不可能的。
有没有更好、更通用的方法来获得所描述的功能?
您可以使用泛型类型和推理。如果您的要求允许这样做,它可能比从基本接口扩展每种类型更容易。此解决方案将您的所有链接放在一个地方,因此它有其自身的缺点,但如果您无法更改原始类型,则对我来说似乎没问题:
type Return<T> =
T extends BarParam ? BarReturn :
T extends FooParam ? FooReturn :
never;
Run Code Online (Sandbox Code Playgroud)
你可以在Playground 中看到它
| 归档时间: |
|
| 查看次数: |
761 次 |
| 最近记录: |