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

{ a: string } can not be assigned to Partial<Omit<P, "a"> & { a: string }> #43846

Closed
vipcxj opened this issue Apr 27, 2021 · 5 comments
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@vipcxj
Copy link

vipcxj commented Apr 27, 2021

Bug Report

πŸ”Ž Search Terms

extends, Partial

πŸ•— Version & Regression Information

4.2.4

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// We can quickly address your report if:
//  - The code sample is short. Nearly all TypeScript bugs can be demonstrated in 20-30 lines of code!
//  - It doesn't use external libraries. These are often issues with the type definitions rather than TypeScript bugs.
//  - The incorrectness of the behavior is readily apparent from reading the sample.
// Reports are slower to investigate if:
//  - We have to pare too much extraneous code.
//  - We have to clone a large repo and validate that the problem isn't elsewhere.
//  - The sample is confusing or doesn't clearly demonstrate what's wrong.

type FunctionType<T> = {
  func(arg: Partial<T>): any;
};

type StringType = {
  str: string;
};

type T = { str: "abc" }
type A = T & StringType;
type B = Omit<T, "str"> & StringType;
const a: Partial<A> = { str: "" }; // not ok.
const b: Partial<B> = { str: "" }; // ok.

function example<T extends Record<string, any>>(ft: FunctionType<Omit<T, "str"> & StringType>) {
  ft.func({ str: "" }); // not ok.
}

according #43125, { a: "string" } can not be assigned to Partial<P> which P extends { a: string } because P.a may extends from string. So I make 2 new version:

  1. T & { a: string }
  2. Omit<T, "a"> & { a: string }.

But still not work.

πŸ™ Actual behavior

At least { a: string } should be assigned to Partial<Omit<P, "a"> & { a: string }>

πŸ™‚ Expected behavior

It not work.

@jcalz
Copy link
Contributor

jcalz commented Apr 27, 2021

Reminds me of #28884, where the compiler doesn't currently perform the kind of analysis needed to verify such assignability for types depending on unresolved generics type parameters like P.

@amcasey
Copy link
Member

amcasey commented Apr 28, 2021

Another issue with strange (but mostly explained?) Omit behavior: #43717

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Apr 29, 2021
@RyanCavanaugh
Copy link
Member

The type system doesn't take Omit as a first-class operation; it's a series of mapped types and conditional types under the hood that aren't resolvable on a generic type in a way that would produce a type that we could identify as a valid assignment target of that expression. There's not much we can do here apart from possibly special-casing, but that's a future endeavor.

@jchook
Copy link

jchook commented Mar 3, 2022

Thanks for the explanation.

Is that why I cannot "fill in" the omitted properties of Omit<T, K> to get T again?

For example:

interface MyType {
  path: string
  params: Record<string, string>
}

function getMyTypeCreator<T extends MyType>(initial: Omit<T, 'params'>) {
  return (params: T['params']): T => ({
    ...initial,
    params,
  })
  // Error: Type 'Omit<T, "params"> & { params: T["params"]; }' is not assignable to type 'T'.
  // 'Omit<T, "params"> & { params: T["params"]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyType'.(2322)
}

@RyanCavanaugh
Copy link
Member

Exactly, yes

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

5 participants