gpt4 book ai didi

typescript - 如何声明泛型类泛型?

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:52 26 4
gpt4 key购买 nike

我正在尝试设计一种方法来声明一个可以返回 Promise 或 rxjs Observable 或具有特定返回类型的大多数 Stream 的函数,但我不知道在 typescript 中声明此函数的正确方法。

一般来说,我希望在我的代码中是这样的:

class Action<T> {
dispatcher: Function
constructor(dist) {
this.dispatcher = dist
}

f = <T>(s: string): T<string> => this.dispatcher('hello'+s)
}

In this way I get the error: 'T is not generic'

对我来说,T 可以是 Promise、Observable 或 Stream

如果我能够拥有与此类似的东西,我可以声明一个特定的调度程序,它根据我的声明方式返回我想要的值

const promiseDispacher = (x:any)=>Promise.resolve(x)
const observableDispacher = (x:any)=>Observable.of(x)

我想要的是当我调用函数 f 时能够以不同的方式使用的能力

 const a = new Action<Promise>(promiseDistpacher)
a.f('random string').then((s: string)=>{
....
})

 const a = new Action<Observable>(observableDistpacher)
a.f('random string').subscribe((s: string)=>{
....
})

已更新

f 是一个函数,它执行一些操作并使用调度程序将结果包装在特定的 T(Promise 或 Stream)中并返回给执行的类函数

最佳答案

尽管不确定您在做什么,但我还是会尝试回答这个问题。作为第一枪,让我们制作T传入的调度程序返回的通用类型,类似于 Promise<any>Observable<any> ReadableStream<any> :

class Action<T> {
dispatcher: (x: any) => T;
constructor(dist: (x: any) => T) {
this.dispatcher = dist
}
f = (s: string) => this.dispatcher('hello' + s);
}

const promiseDispatcher = (x: any) => Promise.resolve(x)
const a = new Action(promiseDispatcher);
a.f("random string").then((s: string) => {
// ...
}); // works

这现在可以工作了,f 的类型对于 Action<T>被推断为 (s: string) => T 类型, 自 a是一个 Action<Promise<any>> , 然后 a.f(s)Promise<any> .请注意,尽管 f有一个T在其返回类型中,f本身并不是您认为的通用函数。通用参数位于 上,一旦您拥有该类的具体实例,它的f function 也是一个具体的函数类型。


这里的一个问题是您可能并不真的想要 a.f(s)成为Promise<any> , 但宁愿看到 Promise<string> .事实证明,由于 TypeScript 目前不支持 higher kinded types非常多,没有通用的方式来表示 T类似 Promise 的东西或 ObservableReadableStream ,它们本身就是通用类型。用conditional types您可以选择一些硬编码类型,例如 Promise<any> , Observable<any> , 和 ReadableStream<any>并将它们转换为 Promise<string> , Observable<string> , 和 ReadableStream<string> ,分别是:

type AppliedToString<T> =
T extends Promise<any> ? Promise<string> :
T extends Observable<any> ? Observable<string> :
T extends ReadableStream<any> ? ReadableStream<string> :
T;

现在如果我们constrain T对于那些硬编码的类型并使用上面的类型函数,我们应该得到类似于你想要的 f 类型的类型。 :

// constrain T
class Action<T extends Promise<any> | Observable<any> | ReadableStream<any>> {
dispatcher: (x: any) => T;
constructor(dist: (x: any) => T) {
this.dispatcher = dist
}
// assert return type of f as AppliedToString<T>
f = (s: string) => this.dispatcher('hello' + s) as AppliedToString<T>;
}
const promiseDispatcher = (x: any) => Promise.resolve(x);
const a = new Action(promiseDispatcher);
a.f("random string").then((s: string) => {
// ...
}); // works

现在如果你检查 a.f的返回类型你会看到它是 Promise<string> .

这样做的缺点是您需要维护一个硬编码列表,而且它也不是特别安全的类型,因为它允许您传入一个返回 Promise<number> 的调度程序。并将其视为 Promise<string> ... 会在运行时爆炸。


如果我想变得更简单和更安全,我会限制 TPromise<string> , Observable<string> , 或 ReadableStream<string>并忘记映射,但要求传入的调度程序采用 string并返回 T :

class Action<T extends Promise<string> | Observable<string> | ReadableStream<string>> {
dispatcher: (x: string) => T;
constructor(dist: (x: string) => T) {
this.dispatcher = dist
}
f = (s: string) => this.dispatcher('hello' + s);
}
// note that x is type string in this:
const promiseDispatcher = (x: string) => Promise.resolve(x)
const a = new Action(promiseDispatcher);
a.f("random string").then((s: string) => {
// ...
})

好的,希望其中一项或多项对您有所帮助。祝你好运!

关于typescript - 如何声明泛型类泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54132960/

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