我想基于对象类型使用不同的通用方法。这是我的代码例:
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
吗?提前致谢
答案 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
})) //
}