Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
jacobamills opened this issue Sep 26, 2024 · 2 comments
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@jacobamills
Copy link

πŸ”Ž 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) (?)

@jcalz
Copy link
Contributor

jcalz commented 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.

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Sep 26, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Design Limitation" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants