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

TS2322: Type '{}' is not assignable to type 'DeepPartial<T>' #123

Open
FrancescoBorzi opened this issue Jan 28, 2020 · 5 comments
Open

TS2322: Type '{}' is not assignable to type 'DeepPartial<T>' #123

FrancescoBorzi opened this issue Jan 28, 2020 · 5 comments
Labels
bug Something isn't working ts issue

Comments

@FrancescoBorzi
Copy link
Contributor

FrancescoBorzi commented Jan 28, 2020

Using ts-essentials version 5.0.0.

I have a function with the following types:

const myFunction = <T extends {}>(someCondition: boolean, object: T): DeepPartial<T> =>
  someCondition ? {} : object;

I know this is a bit weird but this is just to have a minimal bug reproduction: basically my function can return T, a DeepPartial<T> or the empty object {}.

Unfortunately, I get this error:

TS2322: Type '{}' is not assignable to type 'DeepPartial<T>'

However, if I use Partial<T extends {}> I don't get this issue:

const myFunction = <T extends {}>(someCondition: boolean, object: T): Partial<T> =>
  someCondition ? {} : object;

so basically {} can be a Partial<T>, but it can't be a DeepPartial<T>, which is weird.

@quezak
Copy link
Collaborator

quezak commented Jan 28, 2020

Confirmed, thanks for finding this!

Looks like this was introduced at v3.0, when the DeepPartial implementation was "turned inside out" in a refactor -- see the commit here

@krzkaczor @FrancescoBorzi can you see which of the new conditions cause DeepPartial to reject {}? also asking @lucifer1004 since you've made that particular refactor

@quezak
Copy link
Collaborator

quezak commented Jan 28, 2020

The last version (2.12) that worked with {}, in case someone wants to play around comparing to the current version:

export type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends Primitive
    ? T[P]
    : T[P] extends Function
    ? T[P]
    : T[P] extends Date
    ? T[P]
    : T[P] extends Array<infer U>
    ? Array<DeepPartial<U>>
    : T[P] extends ReadonlyArray<infer U>
    ? ReadonlyArray<DeepPartial<U>>
    : DeepPartial<T[P]>
};

@krzkaczor krzkaczor added the bug Something isn't working label Jan 30, 2020
@lucifer1004
Copy link
Contributor

I think there might be some bug related to TypeScript's recursion mechanism when there are conditions.

See the following example:

export type DeepPartial<T> = T extends Builtin
? { [K in keyof T]?: DeepPartial<T[K]> }
: { [K in keyof T]?: DeepPartial<T[K]> };

const myFunction = <T extends {}>(bool: boolean, obj: T): DeepPartial<T> => bool ? {} : obj;
// Type '{}' is not assignable to type 'DeepPartial<T>'.ts(2322)

While

export type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> };

const myFunction = <T extends {}>(bool: boolean, obj: T): DeepPartial<T> => bool ? {} : obj;

@quezak
Copy link
Collaborator

quezak commented Mar 31, 2020

Should we file an issue to TS then? Can we somehow work around this issue? (well, apart from going back to the form before the refactor I linked)

@Beraliv
Copy link
Collaborator

Beraliv commented Apr 27, 2024

The side effect of conditional types, the issue to TypeScript - microsoft/TypeScript#37524

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ts issue
Projects
None yet
Development

No branches or pull requests

5 participants