5

For example:

interface U {
  u: boolean;
}

const f = <T extends U>() => {
  const t: Partial<T> = {u: true};
};

I get the following error:

Type '{ u: true; }' is not assignable to type 'Partial<T>'.ts(2322)

Playground link

Is there a way to fix this without casting to any?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
btmorex
  • 476
  • 5
  • 16
  • Technically, the answer to *"Is there a way to fix this without casting to any?"* is "Yes: `const t: Partial = {u: true} as Partial;`" But that's not really helpful... ;-) Would it be accurate to reword that as *"...without using a type assertion?"* ? – T.J. Crowder Feb 10 '20 at 11:47
  • this works `const t = { u: true } as Partial;` – Stutje Feb 10 '20 at 12:15

1 Answers1

1

The issue, that TypeScript complains about is the following:

Type '{ u: true; }' is not assignable to type 'Partial<T>'.ts(2322)

your function f could be called with:

f<{ u: boolean, v: boolean }>(); // ok since U is "implemented" but not "v"

this opens the option, that your generic and your provided concrete implementation of an object inside the function { u: true } could differ.

The TypeScript compiler doesn't enforce you to define the same type as it extends, you are still able to specify a more specific implementation of U as long as U is fully provided (in this case the boolean flag u).

A few possible solutions are:

Use Type-Cast (as used before):

interface U {
  u: boolean;
}

const f = <T extends U>() => {
  const t: Partial<T> = {u: true} as Partial<T>;
};

f<U>();

Downside: { u: true } could well be replaced with: { v: true } which can cause issues with undefined later on in your code.

Try to re-phrase your function

To tell the compiler to exactly use type U, you could, if possible, try to re-phrase the function and move the constant t as a function parameter.

interface U {
  u: boolean;
}

const f = <T>(u: T) => {
  const t: Partial<T> = u;
};

f<{ u: boolean }>({ u: true });

Consider if generics are relevant

Your function requires a generic type but your function body assigns a concrete type which causes the trouble here. You could consider if generics are relevant there. A generic free alternative would be:

interface U {
  u: boolean;
}

const f = () => {
  const t: Partial<U> = {u: true};
};

f();
Hamed
  • 5,867
  • 4
  • 32
  • 56
r3dst0rm
  • 1,876
  • 15
  • 21