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

Intersection of mapped type of with omit not compatible #51972

Closed
robinchrist opened this issue Dec 20, 2022 · 1 comment
Closed

Intersection of mapped type of with omit not compatible #51972

robinchrist opened this issue Dec 20, 2022 · 1 comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@robinchrist
Copy link

Bug Report

πŸ”Ž Search Terms

omit, mapped type, intersection

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, 3.5.1 up to 4.9.4

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type Column = {value: number}


type RemoveTitles<Type> = {
  [Property in keyof Type]: Omit<Type[Property], 'title'>;
};

class TableDataGenerator2<
  TIn extends { [colName: string]: Column & { title: string } },
  TAdd extends { [colName: string]: Column & { title: string } } = {}
> {

  constructor(
    private callback: (
      index: number,
      row: RemoveTitles<TIn>
    ) => Promise<RemoveTitles<TAdd>>
  ) {}

  chain<TAdd2 extends { [colName: string]: Column & { title: string } }>(
    cb: (
      index: number,
      row: RemoveTitles<TIn> & RemoveTitles<TAdd>
    ) => Promise<RemoveTitles<TAdd2>>
  ): TableDataGenerator2<TIn, TAdd & TAdd2> {
    return new TableDataGenerator2<TIn, TAdd & TAdd2>(async (index, input) => {
      const elem = await this.callback(index, input);
      const elem2 = await cb(index, { ...elem, ...input });
      return { ...elem2, ...elem };
    });
  }
}
Argument of type '(index: number, input: RemoveTitles<TIn>) => Promise<RemoveTitles<TAdd2> & RemoveTitles<TAdd>>' is not assignable to parameter of type '(index: number, row: RemoveTitles<TIn>) => Promise<RemoveTitles<TAdd & TAdd2>>'.
  Type 'Promise<RemoveTitles<TAdd2> & RemoveTitles<TAdd>>' is not assignable to type 'Promise<RemoveTitles<TAdd & TAdd2>>'.
    Type 'RemoveTitles<TAdd2> & RemoveTitles<TAdd>' is not assignable to type 'RemoveTitles<TAdd & TAdd2>'.

πŸ™ Actual behavior

TypeScript does not detect that RemoveTitles<T1> & RemoveTitles<T2> is compatible with RemoveTitles<T1 & T2>

πŸ™‚ Expected behavior

RemoveTitles<T1> & RemoveTitles<T2> is compatible with RemoveTitles<T1 & T2> and should be treated as equivalent, as can be seen in this example

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Jan 4, 2023
@RyanCavanaugh
Copy link
Member

TypeScript does not detect that RemoveTitles<T1> & RemoveTitles<T2> is compatible with RemoveTitles<T1 & T2>

It's not really clear how it could, either - the definition of this type is sufficiently complex that there isn't an obvious way to identify this fact apart from some very difficult counterfactual reasoning about possible inhabitants of T1 and T2.

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

2 participants