首页 > 解决方案 > 打字稿:有没有办法在不转换为类类型的情况下显示属性和方法?

问题描述

我编写了这段打字稿代码来复制我在项目中遇到的问题。我有一个基类(在本例中为“Foo”)和许多从“Foo”扩展的其他类。函数“instanciateFoos”应该能够实例化一个 fooLike 类(在本例中为“Bar”)并以正确的类型返回它。我有很多很长的类名,我很想有一种方法来调用函数,而不必写两次类名。使用我当前的解决方案,我总是必须将返回的对象转换为我已经传递给函数的类,以使打字稿将其识别为类的实例。也许有一些方法可以使用泛型或类似的东西来解决这个问题。

class Foo
{
    constructor() { }
}

class Bar extends Foo
{
    talk()
    {
        console.log("Bar");
    }
}

function instanciateFoos(fooLikeClass: typeof Foo)
{
    return new fooLikeClass();
}


let myBar = instanciateFoos(Bar);

myBar.talk();

// Error: Property 'talk' does not exist on type 'Foo'.ts(2339)


let myBar2 = <Bar>initiateFoos(Bar);

myBar2.talk();

// works

标签: typescriptgenericstypes

解决方案


正如您可能已经猜到的那样,给定generics标签,您可以通过创建instantiateFoos一个通用函数来解决这个问题:

function instantiateFoos<T extends Foo>(fooLikeClass: new () => T) {
  return new fooLikeClass();
}

不是fooLikeClass参数是 type typeof Foo,而是它是 type new () => T,一个无参数构造签名,它产生 type 的实例T,其中T泛型类型参数被约束为 的子类型Foo

现在您的通话可以按需要进行:

let myBar = instantiateFoos(Bar); // let myBar: Bar;
myBar.talk(); // okay

Playground 代码链接


推荐阅读