繁体   English   中英

TypeScript - 如何从方法的参数推断类泛型类型?

[英]TypeScript - How do you infer a class generic type from a method's parameter?

我正在尝试从稍后将调用的方法参数中键入一个泛型类。 直到我们调用带有泛型参数的方法时,才会知道类的泛型类型。 然后,对于任何其他方法,将传递泛型类型。

老实说,对我来说,这似乎功能如此复杂,我什至不确定 TypeScript 有没有办法做到这一点......

这是我希望行为的样子:

class Class<T> {
    foo = (bar: T[]) => {
        /* ... */
        return this;
    };

    baz = (cb: (qux: T) => void) => {
        /* ... */
        return this;
    };
}

new Class() // Here, T should be unknown
    .foo([{ name: "John", id: "123" }]) // Here, it should be infered that T is { name: string, id: string }
    .baz((person) => null) // Here, person should have the type { name: string, id: string }

在这个例子中,当我们实例化ClassT应该是未知的。 然后,当我们将一个对象数组传递给fooT应该被推断为该对象类型,因为bar的类型是T[] 既然T已经被quxqux在将函数传递给baz时应该自动输入qux ( baz(cb: ({ name: string, id: string }) => void) )

请注意,我不想将泛型传递给Class因为我希望稍后对其进行推断。 换句话说,我不想

new Class<{ name: string, id: string }>()

感谢您的回答!

我猜写这个问题就像橡皮鸭调试! 在我发帖后大约几分钟,我发现了这个。 然而,它不是太漂亮,所以我打算让线程打开一段时间,以防出现更好的主意:

class Class<T> {
    foo = <U extends T>(bar: U[]) => {
        /* ... */
        return (this as unknown) as Class<U>; // not pretty
    };

    baz = <U extends T>(cb: (qux: U) => void) => {
        /* ... */
        return (this as unknown) as Class<U>; // not pretty
    };
}

new Class() // Here, T is unknown, as it should be
    .foo([{ name: "John", id: "123" }]) // Here, T becomes U ({name: string, id: string})
    .baz((person) => null); // Here, person is typed {name: string, id: string} Yay!

// This also works!
new Class() // Here, T is unknown, as it should be
    .baz((person: { name: string; id: string }) => null) // Here, T becomes U ({name: string, id: string})
    .foo([{ name: "John", id: "123" }]); // Here, bar is typed { name: string, id: string }[] Yay again!

通过使用扩展类的泛型类型的另一个泛型类型键入方法,我们可以返回this并“安全地”将其键入为Class<U> ,它现在提供实际类型而不是unknown

这里的问题是,这只是工作,因为我们正在返回this同时用新型键入它Class<U> 因此,将对象传递给不返回this方法不会修改它的泛型类型......

class Class<T> {
    public data: T;

    quux = <U extends T>(quuz: U) => {
        this.data = quuz;
        /* ... void */
    };
}

const c = new Class();
c.quux({ name: "John", id: "123" });
c.data // still unknown

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM