Q: Angular Custom Pipe : Resolving promises won't work but calling AsyncPipe will The goal I want to achieve is to have a pipe that would handle the following signature :
any | (() => any | Promise<any>)
So I wrote the following pipe.
public transform(varOrFunc: any | (() => any | Promise<any>)): any {
    if (typeof varOrFunc === 'function') {
        const result = varOrFunc();
        if (result.then) {
            return this.asyncPipe.transform(result);
        } else {
            return result;
        }
    } else {
        return varOrFunc;
    }
}

--
<my-cmp [isDisabled]="myVarOrFunc | varOrFunc></my-cmp> 

Unfortunately this doesn't work as expected.
But
public transform(varOrFunc: any | (() => any | Promise<any>)): any {
    if (typeof varOrFunc === 'function') {
        const result = varOrFunc();
        if (result.then) {
            return result;
        } else {
            return Promise.resolve(result);
        }
    } else {
        return Promise.resolve(varOrFunc);
    }
}

--
<my-cmp [isDisabled]="myVarOrFunc | varOrFunc | async ></my-cmp> 

Does work perfectely fine.
Do you have any idea why ?
Here is a working demo of the problem

A: You can't use the AsyncPipe to synchronously transform an asynchronous result. The way the async pipe works is by storing the promise and triggering a change detection when it's resolved, and caching the result. So the transform method of the async pipe will always return null the first time it's called.
I think that the best way to achieve what your trying to do is by reimplementing some of the async pipe logic in your pipe :

*

*Your pipe needs to be not pure so angular won't cache its result, which means you'll have to do the caching in the pipe to avoid performance issues.

*Use a ChangeDetectorRef to trigger a detectChange when the promise resolves.

for exemple :
@Pipe({ name: "varOrFuncAsync", pure: false })
export class VarOrFuncAsyncPipe implements PipeTransform {

  private lastResult: any = null;
  private lastParam:  any | (() => any | Promise<any>) = null;

  constructor(private _ref: ChangeDetectorRef) {}

  public transform(varOrFunc: any | (() => any | Promise<any>)): any {
    if (this.lastParam === varOrFunc) {
      return this.lastResult;
    }
    this.lastParam = varOrFunc;

    if (typeof varOrFunc === "function") {
      const result = varOrFunc();
      if (result.then) {
        this.lastResult = null;
        result.then(r => this.updateResult(r));
        return null;
      } else {
        this.lastResult = result;
        return result;
      }
    } else {
      this.lastResult = varOrFunc;
      return varOrFunc;
    }
  }

  updateResult(result: any) {
    this.lastResult = result;
    this._ref.detectChanges();
  }
}

