3

I'm getting the Typescript error

Type '{ aaa: string; }' is not assignable to type '{ [P in keyof T]?: T[P]; }'.ts(2322)

related to the const c in the following code

class MyClass<T extends { aaa: string }> {
    public find(aaa: string) {
        const c: { [P in keyof T]?: T[P] } = { aaa };
    }
}

I've looked through many stack overflow posts that don't seem to help because I think this is particularly related to the mapped type.

I would expect that the mapped type defined above would let me use properties defined in the type constraint { aaa: string }.

Is that not true? Is there something about type contraints that aren't enumerable over mapped types?

Thanks in advance

ChrisBellew
  • 1,144
  • 2
  • 12
  • 27
  • 1
    Weird. Same behaviour when using `Partial`. Which is is the same as your definition but still, I had to check. Also, while it doesn't allow direct assignment, TS is fine with `c.aaa = aaa;` : [Playground Link](https://www.typescriptlang.org/play?#code/MYGwhgzhAECyCeBhcUA8AVaBTAHgFywDsATGAb2jCoC5oI8AnAS0IHNoBfAPmjIChog6AAcArgCMQTYNABmLYgAoqYWvWZsAlLwFC9wAPaF60YLQoBtAArQW0ANZZ4B2dHQBdAPy101952gAXl5OAG4+XT1BYAA6FSDKKnC9Dj4OIA) – VLAZ Apr 05 '22 at 10:14
  • I expected it to be because `T` might be `{ aaa: "literal string type"; }` like this: `const x = new MyClass<{ aaa: "example"; }>();`, and then `{ aaa: string; }` isn't assignable to that. But the fix I thought would fix that (`find(aaa: T["aaa"])`) doesn't fix it, so there goes my theory... – T.J. Crowder Apr 05 '22 at 10:16
  • @VLAZ - Excess property checks? Even though all the properties in the type of `c` are optional? No, that probably doesn't make sense. – T.J. Crowder Apr 05 '22 at 10:17
  • 1
    @T.J.Crowder Excess property checks usually come with a different message. However, given that it's showing up in assignment to a literal - maybe? Could be some weird bug with excess property checks over a mapped type that triggers an incorrect error. – VLAZ Apr 05 '22 at 10:18
  • The compiler's not great about higher order type operations but in this case it's right to complain; you can write `const n = new MyClass<{ aaa: "hello" }>().find("goodbye");` and suddenly you're claiming that `{aaa: "goodbye"}` is assignable to `{aaa?: "hello"}`, which it isn't. See [here](https://tsplay.dev/mMMVkm). As such I think this question is a duplicate of https://stackoverflow.com/questions/46980763/why-cant-i-return-a-generic-t-to-satisfy-a-partialt . Anyone disagree? – jcalz Apr 05 '22 at 18:30
  • @jcalz no disagreement. That question seems to be spot-on. – VLAZ Apr 05 '22 at 18:32

0 Answers0