I have the following code:
export type Primitive = boolean|string;
export type ObjectItem = {[k: string]: ObjectItem|Primitive};
export type DynamicItem<T extends ObjectItem|Primitive> = T extends ObjectItem ? ObjectItemInterface<T> : PrimitiveItemInterface<T>;
export interface PrimitiveItemInterface<T extends (ObjectItem|Primitive)> {
value(): T;
set(v: T): void;
}
export interface ObjectItemInterface<T extends ObjectItem> extends PrimitiveItemInterface<T> {
get<K extends keyof T>(k: K): DynamicItem<T[K]>;
}
const example: ObjectItemInterface<{
enabled: boolean
}> = null;
example.get('enabled').set(true); //Argument of type 'boolean' is not assignable to parameter of type 'never'.ts(2345)
Why it thinks that there is never
type?
I want it to see the boolean type.
CodePudding user response:
The problem is that you use boolean
as a naked parameter type, which makes it used as
solution is to stop the distributive behavior
export type DynamicItem<T extends ObjectItem | Primitive> = [T] extends [ObjectItem] ? ObjectItemInterface<T> : PrimitiveItemInterface<T>;
//=======Update=========
I found the explanation why OP got never, explanation I quote from discord:
when you declare a type, the inferred parameter types on the function do not override
so v can be any in the function literal (because typescript is refusing to infer from the union type A)
but when you call a, typescript does the true & false = never and refuses to allow you call `a`