打字稿:构造函数重载

Typescript: constructor overloading

我需要将这些 Java 构造函数重载转换为 Typescript:

public QueryMixin() {
    this(null, new DefaultQueryMetadata(), true);
}

public QueryMixin(QueryMetadata metadata) {
    this(null, metadata, true);
}

public QueryMixin(QueryMetadata metadata, boolean expandAnyPaths) {
    this(null, metadata, expandAnyPaths);
}

public QueryMixin(T self) {
    this(self, new DefaultQueryMetadata(), true);
}

public QueryMixin(T self, QueryMetadata metadata) {
    this(self, metadata, true);
}

public QueryMixin(T self, QueryMetadata metadata, boolean expandAnyPaths) {//...}

我试过创建这些构造函数并查看了那里,但我一直无法弄清楚如何获得它...

有什么想法吗?

constructor();  <<<1>>>
constructor(metadata: QueryMetadata);
constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
constructor(self: T);
constructor(self: T, metadata: QueryMetadata);
constructor(selfOrMetadata: T | QueryMetadata, expandAnyPaths: boolean) {
    this.self = selfOrMetadata;  <<< PROBLEM HERE
    this.metadata = selfOrMetadata;  <<< PROBLEM HERE
    this.expandAnyPaths = expandAnyPaths;
}

<<<1>>> 我收到了这条编译消息:

Overload signature is not compatible with function implementation.

你可以实现你想要的构造函数重载,但你必须执行一些类型检查才能实现...我不知道 QueryMetadata 是什么样子,但你应该能够从这个独立的例子中得到灵感。

我正在使用自定义类型保护来分隔这些联合类型:

interface QueryMetadata {
    metadata: string;
}

function isQueryMetadata(obj: any): obj is QueryMetadata {
    return (obj && obj.metadata);
}

class Example<T> {

    private metadata: QueryMetadata;
    private self: T;
    private expandAnyPaths: boolean;

    constructor(metadata: QueryMetadata);
    constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
    constructor(self: T);
    constructor(self: T, metadata: QueryMetadata);
    constructor(selfOrMetadata: T | QueryMetadata, expandOrMetadata: boolean | QueryMetadata = false) {
        if (isQueryMetadata(selfOrMetadata)) {
            this.metadata = selfOrMetadata;
        } else {
            this.self = selfOrMetadata;
        }

        if (isQueryMetadata(expandOrMetadata)) {
            this.metadata = expandOrMetadata;
        } else {
            this.expandAnyPaths = expandOrMetadata;
        }
    }
}

替代工厂方法

如果您正在编写新内容,您可能更愿意使用工厂方法来构建您的 class...

interface QueryMetadata {
    metadata: string;
}

class Example<T> {

    private metadata: QueryMetadata;
    private self: T;
    private expandAnyPaths: boolean;

    protected constructor() { }

    static fromMetadata<T>(metadata: QueryMetadata, expandAnyPaths: boolean = false) {
        const example = new Example<T>();
        example.metadata = metadata;
        example.expandAnyPaths = expandAnyPaths;
    }

    static fromSelf<T>(self: T, expandAnyPaths: boolean = false) {
        const example = new Example<T>();
        example.self = self;
        example.expandAnyPaths = expandAnyPaths;
    }
}

const example1 = Example.fromSelf('Some Value');
const example2 = Example.fromSelf('Some Value', true);
const example3 = Example.fromMetadata({ metadata: 'val' });
const example4 = Example.fromMetadata({ metadata: 'val' }, true);