3

I came across a curious Typescript assignment error and I'm trying to understand more about why it doesn't work. For reference I'm using TS 3.9.2.

The code:

function test<U extends object>(a: U, k: keyof U) {
    const x: Partial<U> = { [k]: a[k] };
    // ...
}

The error:

Type '{ [x: string]: U[keyof U]; }' is not assignable to type 'Partial<U>'.

The problem is only present when I'm using generics, for example if instead of U I use a concrete interface, then it works as expected.

I'm assuming that the type system in not able to infer correctly the keys of U and use them during the assignment, why is that? I inspect the type of k inside { [k]: a[k] } it correctly returns keyof U so I don't fully understand why the type system can't use that information to check if the assignment is legal and generalize k to string.

Thank you.

1 Answers1

0

I think, the only reason, that it's not working, that typescript doesn't fully understand your intentions, because you create a new Object and there is no information about it.

In this case better to tell compiler, that now you have Partial of original Object like that

function test<U>(a: U, k: keyof U) {
    const x: Partial<U> = { [k]: a[k] } as Partial<U>;

    return x;
}

and it will work

Slawa Eremin
  • 5,264
  • 18
  • 28
  • I agree, that will work as expected, but I wanted to understand a little better why it works with a concrete interface and doesn't work with generics. – Gianluca Venturini Aug 04 '20 at 05:18