TypeScript通用方法检查接口和强制转换

时间:2018-01-05 09:29:56

标签: typescript generics interface casting

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

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

吗?

提前致谢

1 个答案:

答案 0 :(得分:0)

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

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
    })) // 
}