Not planned
Description
π Search Terms
"conditional type equality", "transitive generic type equality"
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed https://github.com/Microsoft/TypeScript/wiki/FAQ
β― Playground Link
π» Code
type Template<T> = (params: T) => void;
interface BindingParams {
message: string;
}
interface RenderingParams {
printMessage: Template<null>;
}
const bindingTemplate: Template<BindingParams> =
(params: BindingParams) => console.log(params.message);
const renderingTemplate: Template<RenderingParams> =
(params: RenderingParams) => params.printMessage(null);
function bind<T, P extends Partial<T>>(t: Template<T>, p: P) {
const boundTemplate = () => {};
return boundTemplate as unknown as Template<P extends T ? null : Omit<T, keyof P>>;
}
function render<T>(t: Template<T>, p: T): void {
t(p);
}
function renderGenerically<T>(t: Template<T>, p: T) {
const boundTemplate = bind(t, p);
render(renderingTemplate, {printMessage: boundTemplate});
}
function renderSpecifically() {
const boundTemplate = bind(bindingTemplate, {message: 'foo'});
render(renderingTemplate, {printMessage: boundTemplate});
}
renderGenerically(bindingTemplate, {message: 'foo'});
renderSpecifically();
π Actual behavior
Got the error:
Type 'null' is not assignable to type 'T extends T ? null : Omit<T, keyof T>'
Seems like the TS compiler should be able to figure out that T extends T
is true
?
π Expected behavior
No error. Since T extends T
should be true
, null
should be assignable to null
Additional information about the issue
This may be related to #27024 (comment) (?)
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
jcalz commentedon Sep 26, 2024
Working as intended as per #46429; the check needed for this to work does very bad things to compiler performance.
P extends T ? null : Omit<T, keyof P>
is a distributive conditional type, so TS doesn't try to do it. If you can make it non-distributive like[P] extends [T] ? null : Omit<T, keyof P>
then it should start working for you. If not, just use a type assertion and move on.typescript-bot commentedon Sep 29, 2024
This issue has been marked as "Design Limitation" and has seen no recent activity. It has been automatically closed for house-keeping purposes.