打字稿:超载类似级联的构造函数



我需要将这些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) {
    this.self = self;
    this.metadata = metadata;
    this.expandAnyPaths = expandAnyPaths;
}

我尝试过创建这些构造函数在那边看一下,但是我无法弄清楚如何获得它...

有什么想法?

constructor();
constructor(metadata: QueryMetadata);
constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
constructor(self: T);
constructor(self: T, metadata: QueryMetadata);
constructor(???) {
    this.self = self;  <<< ???
    this.metadata = selfOrMetadata;  <<< ???
    this.expandAnyPaths = expandAnyPaths;
}

似乎您实际想要的是支持当前或缺失参数的任何组合,并使用简单的默认值。使用3个参数,有8个开/关组合。因此,尽管Typescript支持过载,但编写8个超载以进行类型安全是不理想的。

但是使用命名参数(代替位置)将简化实现。可以轻松地添加更多参数,而无需指数化更多的过载。

interface QueryMetadata { }
class DefaultQueryMetadata implements QueryMetadata { }
interface QueryMixinParams<T> {
    self: T;
    metadata: QueryMetadata;
    expandAnyPaths: boolean;
}
class QueryMixin<T> implements QueryMixinParams<T> {
    self: T;
    metadata: QueryMetadata;
    expandAnyPaths: boolean;
    constructor({
        self = null,
        metadata = new DefaultQueryMetadata(),
        expandAnyPaths = true,
        }: Partial<QueryMixinParams<T>> = {}) {
        this.self = self;
        this.metadata = metadata;
        this.expandAnyPaths = expandAnyPaths;
        console.log(this);
    }
}
// Any combination of parameters is supported
new QueryMixin();
new QueryMixin({});
new QueryMixin({ self: {} });
new QueryMixin({ self: {}, metadata: {} });
new QueryMixin({ self: {}, metadata: {}, expandAnyPaths: false });
new QueryMixin({ self: {}, expandAnyPaths: false });
new QueryMixin({ metadata: {} });
new QueryMixin({ metadata: {}, expandAnyPaths: false });
new QueryMixin({ expandAnyPaths: false });

在打字稿游乐场

尝试一下

在打字稿中,您可以为方法/构造函数指定多个签名,但是单个实现。由实施来确定调用哪个过载。

在您的情况下,它可能看起来像这样:

constructor();
constructor(metadata: QueryMetadata);
constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
constructor(self: T);
constructor(self: T, metadata: QueryMetadata);
constructor() {
    let self: T = null;
    let metadata : QueryMetadata = null;
    let expandAnyPaths = true;
    if(arguments.length > 0) {
        // Asuming QueryMetadata is a class
        if(arguments[0] instanceof QueryMetadata) { 
            expandAnyPaths = arguments[1] || true;
            metadata = arguments[0];
        }
        else {
            self = arguments[0]
            metadata = arguments[1];
        }
    }
    this.self = self;
    this.metadata = metadata || new DefaultQueryMetadata();;
    this.expandAnyPaths = expandAnyPaths;
}

注意:实现签名是从外界隐藏的(即在寻找Aprime构造函数时不考虑解决方案)。这就是为什么我们有两次空的构造函数签名,一次是用于公众消费,并且一次是实施签名。

最新更新