onrejected 함수의 타입은 (reason : any) => TResult | PromiseLike<TResult>입니다. 함수에 반환값이 없으므로 void 타입이 되고, TResult가 void가 됩니다. catch 메서드의 반환값은 Promise<T | TResult>인데 T는 boolean이고, TResult는 void이므로 Promise<boolean | void>가 됩니다.
여기에 await을 붙이면 Awaited<Promise<boolean | void>>가 되어 규칙 2번에 의해 Awaited<boolean | void>가 되고, 다시 규칙 1번에 의해 boolean | void가 됩니다. 그래서 chaining의 타입이 boolean | void로 추론되는 것입니다.
이렇게 Promise.resolve, Promise.all, 메서드 체이닝의 타입을 분석해보았습니다. 한 가지 알아두어야 할 점은 Promise 인스턴스가 아니더라도 객체가 { then(onfulfilled : () => any): any } 형식이기만 하면 await을 적용할 수 있다는 점입니다. 구조적 타이핑에 의해 { then(onfulfilled : () => any): any } 객체도 PromiseLike 타입으로 치기 때문입니다.
type Result = Awaited<{ then(onfulfilled: (value: string | number) => any): any }>;
// type Result = string | number