【问题标题】:TypeScript Generic method check Interface and castTypeScript 通用方法检查接口和强制转换
【发布时间】:2018-01-05 09:29:56
【问题描述】:

我想根据对象类型使用不同的通用方法。这是我的代码示例:

export interface IStorable {
    Enable : boolean;
}

async GetItemStored<T extends IStorable>(toExecute : () => Promise<T>){//Some Code}

async GetItem<T>(toExecute : () => Promise<T>){//Some Code}


Main<T>(toExecute : () => Promise<T>){
    if(this.IsStorable(toExecute)){
        await this.GetItemStored(this.CastInStorable(toExecute));
    } else {
        await this.GetItem(toExecute);
    }
}

IsStorable<T>(() => Promise<T>) :boolean {
    // ???
}

CastInStorable<T, U extends IStorable >(() => Promise<T>) : () => Promise<U> {
    // ???
}

你能帮我写两个函数 IsStorable 和 CastInStorable

提前致谢

【问题讨论】:

    标签: typescript generics interface casting


    【解决方案1】:

    除非您在创建时以某种方式标记承诺,否则除非您等待结果,否则无法知道结果类型:

    IsStorable(value: any) : value is IStorable  {
        return (value as any).Enable !== undefined;
    }
    async Main<T>(toExecute : () => Promise<T>){
        let result = await toExecute();
        if(this.IsStorable(result)){
            // result will be ISortable beacuse IsStorable si a type guard
            let asSortable = result;
            await this.GetItemStored(()=> Promise.resolve(asSortable));
        } else {
            await this.GetItem(()=> Promise.resolve(result));
        }
    }
    

    编辑

    标记 toExecute 函数的另一种方法可能如下所示:

    type SortablePromiseGenerator<T> = { () : Promise<T & IStorable>; isSortable: true };
    type NonSortablegenerator<T> = () => Promise<T & {Enable? : never }>;
    
    ....
    IsStorable<T>(toExecute: SortablePromiseGenerator<T> | NonSortablegenerator<T>) : toExecute is SortablePromiseGenerator<T> {
        return (toExecute as SortablePromiseGenerator<T>).isSortable;
    }
    
    sortableGenerator<T extends IStorable>(toExecute : ()=> Promise<T>) : SortablePromiseGenerator<T>{
        let toExecuteResult = toExecute as SortablePromiseGenerator<T>;
        toExecuteResult.isSortable  = true;
        return toExecuteResult
    }
    sample (){
        this.Main(()=> Promise.resolve({})) // call with anything
        this.Main(this.sortableGenerator(()=> Promise.resolve({}))) // will fail at compile if result is not sortable
    
        // Ok call 
        this.Main(this.sortableGenerator(()=> Promise.resolve({
            Enable : true
        })));
    
        // Will fail at compile time, if the result conforms to the ISortable interface it must be wraped with sortable
        this.Main(()=> Promise.resolve({
            Enable : true
        })) // 
    }
    

    【讨论】:

    • 您好,感谢您的回复。不幸的是,我现在不应该解决这个承诺。可能会在其他 TypeScript 版本中实现
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 2019-05-03
    • 2011-01-05
    • 2018-08-09
    • 2013-02-07
    相关资源
    最近更新 更多