打字稿 - return 特定 class 使用类型化函数的混合数组实例

typescript - return specific class instance from mixed array using typed function

是否可以使用类型化函数从混合数组中检索特定类型?

public plugins: (Tool|Service)[] = [];
getTools(): Tool[]{
    return this.plugins.filter(t => t instanceof Tool);
}

到目前为止我还没有运气。打字稿正在抛出以下消息

TS2322: Type '(Tool | Service)[]' is not assignable to type 'Tool[]'. Property 'onclick' is missing in type 'Service'.

有什么方法可以在这里将函数类型设置为 Tool[] 吗?

完整代码如下:

interface Required {
    id: string
    title: string
    owner: string
    type: 'user' | 'admin'
}

class P {
    id; title; owner; type;
    constructor(config: Required){
        this.id = config.id || 'uniqid';
        this.title = config.title || 'Title';
        this.owner = config.owner || 'user';
        this.type = config.type;
    }
}

interface ToolRequired extends Required{
    onclick: () => void
}

class Tool extends P {
    onclick;
    constructor(config = {} as ToolRequired){
        super(config);
        this.type = 'tool';
        this.onclick = config.onclick
    }
}

class Service extends P {
    constructor(config = {} as Required){
        super(config);
        this.type = 'service'
    }
}

class Storag {
    static types = {
        tool: Tool,
        service: Service,
        undefined: Tool,
    };
    public plugins: (Tool|Service)[] = [];
    setPlugin(config = {} as Required){
        const Type = Storag.types[config.type];
        this.plugins.push( new Type(config) );
    }
    getTools(): Tool[]{
        return this.plugins.filter(t => t instanceof Tool);
    }
}

最后加上一个 as Tool[]

public plugins: (Tool|Service)[] = [];
getTools(): Tool[]{
    return this.plugins.filter(t => t instanceof Tool) as Tool[]; // << here
}

你需要这样做的原因是因为 Typescript 编译器不够聪明,无法知道当你进行这样的过滤时,它会 return Tools。任何数组上的 .filter 通常 return 与前一个数组的类型相同,这是编译器 假定的这里 - Tool|Service 数组。

编译器足够聪明,知道 Tool|Service 可以减少到只有 Tools - 因此,你可以在最后做一个 as Tool[]告诉编译器I know what I'm doing - the type that ".filter" returns will only be Tools here,编译器会听取并尊重它。

您可以在此处阅读有关 as 关键字的更多信息:https://www.typescriptlang.org/docs/handbook/basic-types.html(向下滚动或搜索 "Type assertions")。