Closed
Description
TypeScript Version: 3.9.4
Search Terms:
is assignable to the constraint of type
Code
const isNil = <A extends any>(a: A) => a === undefined || a === null;
type DeepRequired<O extends {}> = {
[key in keyof O]: O[key] extends {}
? DeepRequired<O[key]>
: NonNullable<O[key]>;
};
export function assertNonNullable<O extends {}>(
object: O,
): asserts object is DeepRequired<O> { // throws
Object.entries(object).forEach(([key, value]) => {
if (typeof value === 'object' && value !== null) {
assertNonNullable(value);
}
if (isNil(value)) {
throw new Error(`Key ${key} is required, but the provided value is nil`);
}
});
}
interface MaybeA {
a?: number;
}
const a: MaybeA = { a: undefined };
assertNonNullable(a);
const b = a.a;
Expected behavior:
No error is thrown
Actual behavior:
The following error is thrown:
A type predicate's type must be assignable to its parameter's type.
Type 'DeepRequired<O>' is not assignable to type 'O'.
'DeepRequired<O>' is assignable to the constraint of type 'O', but 'O' could be instantiated with a different subtype of constraint '{}'.
Type 'O[key] extends {} ? DeepRequired<O[key]> : NonNullable<O[key]>' is not assignable to type 'O[key]'.
Type 'DeepRequired<O[key]> | NonNullable<O[key]>' is not assignable to type 'O[key]'.
Type 'DeepRequired<O[key]>' is not assignable to type 'O[key]'.
Playground Link:
Related Issues: