Skip to content

Type 'null' is not assignable to type 'T extends T ? null : Omit<T, keyof T>' #60076

@jacobamills

Description

@jacobamills

πŸ”Ž Search Terms

"conditional type equality", "transitive generic type equality"

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.7.0-dev.20240926#code/C4TwDgpgBAKhC2YA2BDYEA8MB8UC8UAFGCgE4rwDOAXLAJT64BuA9gJYAmA3AFA9sA7dKQBmKAMbQAQoI6CA5gAUyFSlADePKFHgRKlFPIi1KwUgt4BfPoOFjJUAEoQBHCOYFKVVDVqhgPYABZPQMjWjhEVHQMAQBXJCRsKz5xFgFTKAAjWQVI5DRjWAQCmJlXBWVyKlw8P2JvGihyuU8q1QY8XDSMliQIADokFnkG6soB3X1DCDpeHh7M0hc3D3l86KKNwoxnV3dKxtr6knHaPdXD8c7cU9UBgNsQ6aNCeMS5vhE4gXFgNnS2VkWAANFBFFAIAAPdCuNRVf4oJBYbDYQjACIlTYosFgWiKBiabSLYDZFg-DjbdD4Ig3DSWXjaZbAOKkARkilU6AoNQ-ADWAhYAHd2TzilEdhDobCOGoYFAAPxQd5IKC0ADy8DYwFBUD5EBALBE4NRKR431+-0By32pBR6MxEpiOFxETotFYnF82mAxE+1nNPz+APZNtWAHEXAdxEikCB7RjxaVMC7-G7vVASRzXFyaTlXOjcZ8mSt3IQwwdPFywepHkJnmEillyTmsYVLP6vkGraHS6QAMqQcRsERsGOJECEQl+LPNzlt6kEfMcQjLvILiA1qaN2gAchELBYu47jKgFdI5b766dm40deCoRmtDnrZvJ54AfPkYE0djk7XVYbluj7hFA+6HsenznoOEDDqO45xlOXBAA

πŸ’» 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

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions