打字稿通用参数比较

  • 本文关键字:参数 比较 typescript
  • 更新时间 :
  • 英文 :


所以在Typescript的泛型指南末尾有这段代码

class BeeKeeper {
hasMask: boolean = true;
}
class ZooKeeper {
nametag: string = 'abc';
}
class Animal {
numLegs: number = 123;
}
class Bee extends Animal {
keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
keeper: ZooKeeper = new ZooKeeper();
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}
createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

该程序只创建一些类,然后定义一个创建给定类实例的方法。但是,当我们尝试与可变c进行比较时,会出现一个问题。例如,如果我们想检查是否c == Lion那么 Typescript 会抛出一个错误(游乐场链接(。有谁知道一种方法可以在保持类型检查的同时进行此类比较?

您可以使用类型保护。

它看起来像这样:

type Constructor<T extends {} = {}> = new (...args: any[]) => T;
function typeGuard<T>(o: any, className: Constructor<T>): o is T {
return o === className;
}
function createInstance<A extends Animal>(c: Constructor<A>): A {
if (typeGuard(c, Lion)) {
return new c('Lion initialized')
}
return new c();
}

另请注意Constructor<A>的用法 - 您提到您的构造函数将接收基于类型的参数 - 这无法通过您的实现实现,因为您的构造函数定义没有接收任何参数,因此您应该使用Constructor<A>将任意数量的参数传递给构造函数(由您决定将正确的参数传递给正确的类型构造函数(。

考虑到所有这些,我建议采用一种更干净、更简单的方法。首先定义可以创建的键和相应类型的映射:

type TypeMap = {
"lion": Lion,
"bee": Bee
}

然后只需创建工厂函数,该函数将建议可能的参数("lion" |"bee"(在调用时,如果输入了未知参数,则显示错误并解析正确的返回类型。

function createSimpleInstance<T extends keyof TypeMap>(c: T): TypeMap[T] {
let instance: Animal;
switch (c) {
case "lion":
instance = new Lion("Lion initialized");
break;
case "bee":
instance = new Bee();
break;
default:
throw new Error("Unknown type");
}
return instance as TypeMap[T];
}

这样做的最大好处是,您可以在createSimpleInstance中创建LionBee的精确实例,这有助于您自动完成每个构造函数所需的确切参数。

请看游乐场。

你可以用if(c === instanceof Lion)

例:

class BeeKeeper {
hasMask: boolean = true;
}
class ZooKeeper {
nametag: string = 'abc';
}
class Animal {
numLegs: number = 123;
}
class Bee extends Animal {
keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
keeper: ZooKeeper = new ZooKeeper();
}
function createInstance<A extends Animal>(c: new () => A): A {
const newInstance = new c();
if(newInstance instanceof Lion) {
console.log('Im a Lion');
}
return newInstance;
}
createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

希望这有效,并度过美好的一天:)

你试过以下方法吗?


if(c instanceof Lion) {希望我正确理解您的问题。

我正在寻找一种无需创建类实例即可执行此操作的方法。

简单且有效:

function createInstance<A extends Animal>(c: new () => A): A {
const lion: typeof Lion = Lion;
if (lion.toString() === c.toString()) {
console.log("Lion detected")
}
return new c();
}

最新更新