Typescript 使用类作为模板还是参数?

Typescript 使用类作为模板还是参数?,typescript,Typescript,假设我想要一个类dict,这样我就可以管理本地唯一的类(每个类dict实例) 我试图实现以下内容,但似乎是多余的: // call as b.add<A>(new A()) public add<T>(t: T): T { this.kvp[t.name] = t; return t; } // call as b.get<A>(A) public get<T>(t: any): T { return this.kvp[t.name]

假设我想要一个类dict,这样我就可以管理本地唯一的类(每个类dict实例)

我试图实现以下内容,但似乎是多余的:

// call as b.add<A>(new A())
public add<T>(t: T): T {
  this.kvp[t.name] = t;
  return t;
}

// call as b.get<A>(A)
public get<T>(t: any): T {
  return this.kvp[t.name] as any as T;
}

我怎样才能做到这一点?提前感谢。

我们将
A级
作为
new()=>A级
。所以你必须给出
get(t:new()=>t)

下面是如何在typescript中完全完成的:

class A {
}

class ClassDict {
    kvp: { [k: string]: any } = {};

    public add<T>(t: T){
        this.kvp[t.constructor.name] = t;
    }
    public get<T>(t: new()=>T) {
        return this.kvp[t.name] as T;
    }
    public update<T>(t:T) {
        this.kvp[t.constructor.name] = t;
    }
    public remove<T>(t: new()=>T) {
        this.kvp[t.name] = undefined;
    }
}
let b = new ClassDict()

b.add<A>(new A())
let d = b.get(A); // typeof d is A
b.update(new A())
b.remove(A)

当使用
--lib
时,您必须指定typescript应该使用的所有库,包括默认库,此处需要明确提及它隐式使用的库。

我更改了API,该API只支持构造函数。(
update
remove
被省略,因为它们是相同的)

type ComponentConstructor=new(e:IEntity)=>C;
类实体实现了可扩展性{
受保护的_组件:{[k:string]:IComponent};
公共AddComponent(ctor:ComponentConstructor):C{
常数k=(如有)。名称;
如果(此._组件[k]==未定义){
常数c=新的系数(本);
这是._分量[k]=c;
}否则{
console.warn(k+'已存在');
}
将此返回。_组件[k]作为C;
}
公共GetComponent(ctor:ComponentConstructor):C{
常数k=(如有)。名称;
将此返回。_组件[k]作为C;
}
}
//用户案例
类MyE扩展了ecs.Entity{}
类MyC扩展了ecs.Component{}
常数e=新的MyE();
常数c=e.AddComponent(MyC);
e、 GetComponent(MyC);

t.name的本意是什么?它没有在代码中的任何地方定义shown@MoreThanTom它是内置字段。每个构造函数都可以调用它来获取类的名称。您可以在控制台
classa{}中尝试;A.name
。在我的示例中,它将返回
'A'
语义错误TS2339属性'name'在类型'new()=>T'
上不存在,您在哪一行得到此错误?您使用的ts版本是什么。上面共享的操场链接中似乎没有错误。
get
的实现您正在使用哪个版本的ts?你检查过上面的链接了吗?似乎没有错误。
typescript
3.1.2
。我正在使用
vscode
npm
。我使用了
tsc
进行编译并得到了错误。在
typescript
中不建议使用
any
。你只是绕过了它。而是直接使用javascript。
// creates an object of A
// since param is instance of A, it is supposed to know it
b.add(new A())

// updates an object of A
// same as add
b.update(new A())

// returns an object of A
b.get(A);
// or
b.get<A>()

// removes an object of A, this might be easier as it returns void
b.remove(A)
// or
b.remove<A>()
class A {
}

class ClassDict {
    kvp: { [k: string]: any } = {};

    public add<T>(t: T){
        this.kvp[t.constructor.name] = t;
    }
    public get<T>(t: new()=>T) {
        return this.kvp[t.name] as T;
    }
    public update<T>(t:T) {
        this.kvp[t.constructor.name] = t;
    }
    public remove<T>(t: new()=>T) {
        this.kvp[t.name] = undefined;
    }
}
let b = new ClassDict()

b.add<A>(new A())
let d = b.get(A); // typeof d is A
b.update(new A())
b.remove(A)
tsc test.ts --lib 'dom','es2018'
type ComponentConstructor<C extends IComponent> = new (e: IEntity) => C;

class Entity implements IEntity {
    protected _components: { [k: string]: IComponent };

    public AddComponent<C extends IComponent>(ctor: ComponentConstructor<C>): C {
      const k = (ctor as any).name;
      if (this._components[k] === undefined) {
        const c = new ctor(this);
        this._components[k] = c;
      } else {
        console.warn(k + ' already exists.');
      }
      return this._components[k] as C;
    }

    public GetComponent<C extends IComponent>(ctor: ComponentConstructor<C>): C {
      const k = (ctor as any).name;
      return this._components[k] as C;
    }
}

// user case
class MyE extends ecs.Entity { }
class MyC extends ecs.Component { }

const e = new MyE();
const c = e.AddComponent(MyC);
e.GetComponent(MyC);