【问题标题】:Typescript: Is there a way to show properties and methods without casting to class type?打字稿:有没有办法在不转换为类类型的情况下显示属性和方法?
【发布时间】:2021-10-15 06:47:07
【问题描述】:

我编写了这段打字稿代码来复制我在项目中遇到的问题。我有一个基类(在本例中为“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

【问题讨论】:

  • 举个更好的例子... 在 Unity (C#) 中,您可以像这样向游戏对象添加组件: transform = gameObject.addComponent();在这里,类名只需要一次,因为泛型在 C# 中是如何工作的(或者至少我是这么认为的)

标签: typescript generics types


【解决方案1】:

您可能已经猜到了,给定generics 标签,您可以通过将instantiateFoos 设为generic 函数来解决此问题:

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

fooLikeClass 参数不是typeof Foo 类型,而是new () =&gt; T 类型,一个无参数construct signature,它产生T 类型的实例,其中T 是泛型类型参数constrainedFoo 的子类型。

现在您的通话可以正常工作了:

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

Playground link to code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 2015-07-19
    • 1970-01-01
    相关资源
    最近更新 更多