gpt4 book ai didi

typescript - 将 TypeScript 的 InstanceType 泛型与抽象类一起使用?

转载 作者:搜寻专家 更新时间:2023-10-30 21:27:52 24 4
gpt4 key购买 nike

TypeScript 2.8 添加了一个新的核心类型InstanceType,可用于获取构造函数的返回类型。

/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;

此功能非常好,但在使用抽象类时会崩溃,根据 TypeScript 的类型系统,抽象类没有 new 声明。

起初,我认为我可以通过创建一个类似但限制较少的类型来绕过这个限制(删除 extends new (...args: any[]) => any 守卫) :

export type InstanceofType<T> = T extends new(...args: any[]) => infer R ? R : any;

但是当传递一个抽象类时它也会分崩离析,因为它无法推断返回类型并且默认为 any。这是一个使用模拟 DOM 作为示例的示例,尝试进行类型转换。

abstract class DOMNode extends Object {
public static readonly TYPE: string;
constructor() { super(); }
public get type() {
return (this.constructor as typeof DOMNode).TYPE;
}
}

class DOMText extends DOMNode {
public static readonly TYPE = 'text';
constructor() { super(); }
}

abstract class DOMElement extends DOMNode {
public static readonly TYPE = 'text';
public static readonly TAGNAME: string;
constructor() { super(); }
public get tagname() {
return (this.constructor as typeof DOMElement).TAGNAME;
}
}

class DOMElementDiv extends DOMElement {
public static readonly TAGNAME = 'div';
constructor() { super(); }
}

class DOMElementCanvas extends DOMElement {
public static readonly TAGNAME = 'canvas';
constructor() { super(); }
}

// Create a collection, which also discards specific types.
const nodes = [
new DOMElementCanvas(),
new DOMText(),
new DOMElementDiv(),
new DOMText()
];

function castNode<C extends typeof DOMNode>(instance: DOMNode, Constructor: C): InstanceofType<C> | null {
if (instance.type !== Constructor.TYPE) {
return null;
}
return instance as InstanceofType<C>;
}

// Attempt to cast the first one to an element or null.
// This gets a type of any:
const element = castNode(nodes[0], DOMElement);
console.log(element);

如果构造函数是抽象类,有什么方法可以将变量转换为传递的构造函数的实例?

注意:我试图避免使用 instanceof,因为 JavaScript 的 instaceof 是非常有问题的(同一模块的 2 个不同版本具有不同的构造函数实例)。

最佳答案

您可以查询抽象原型(prototype) 的类型以获得其实例的类型。这并不要求该类型具有 new 签名,只是它具有 prototype 属性。抽象类没有 new 签名,但它们有 prototype 属性。

这是它的样子

function castNode<C extends typeof DOMNode>(
instance: DOMNode,
Constructor: C
): C['prototype'] | null {
if (instance.type !== Constructor.TYPE) {
return null;
}
return instance;
}

类型位置中的表达式C['P'] 称为索引访问类型。它是 type C 中名为 P 的属性的 的类型。

关于typescript - 将 TypeScript 的 InstanceType 泛型与抽象类一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50033794/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com