0

TypeScript has no trouble letting me assign the myValue field on objects of this type, but I couldn't figure out to directly instantiate one of these objects and assign myValue at the same time.

interface FooInterface {
  myValue: number;
}

class FooClass implements FooInterface {
  myValue: number;
}

declare type ShortHandEqualType = string | number | boolean | Date;
declare type KeyOf<MT extends object> = Extract<keyof MT, string>;

type Bar<MT extends object> = {
  [P in KeyOf<MT>]?: (MT[P] & ShortHandEqualType);
}

function run<T extends FooInterface>(item: Bar<T>) {
  // Success
  item.myValue = 1;

  // Success
  const x: Bar<T> = {myValue: undefined};
  x.myValue = 2;

  // Success
  const y: Bar<T> = {};
  y.myValue = 3;

  // Error: Type '{ myValue: 4; }' is not assignable to type 'Bar<T>'
  const z: Bar<T> = {myValue: 4};
}

I tried making the field non-optional, but that didn't help.

Mike Fisher
  • 389
  • 1
  • 7
  • 3
    It's one of those places TS is inconsistent; technically it *should* be an error, because you might pass an a value of type `{ myValue: 1 | 2 | 3 }` as `T`, and the output of `{ mvValue: 4 }` is not assignable to that type. The fact that it lets you do `const z: Bar = {}; z.myValue = 4;` is just TS being inconsistent TS. If you just want to do the assignment and not worry, use a type assertion like `const z = {myValue: 4} as Bar`. I'm almost positive this question has been asked before but I haven't found a very specific duplicate yet – jcalz Oct 26 '20 at 20:41
  • 3
    There's always [the old standby](https://stackoverflow.com/questions/46980763/why-cant-i-return-a-generic-t-to-satisfy-a-partialt) – jcalz Oct 26 '20 at 20:43
  • @jcalz Is it safe to say you can never safely assign to a field inside a function that doesn't that doesn't know the exact type of the object? It seems quite restrictive that you never know what set of values might be valid for any field. – Mike Fisher Oct 26 '20 at 20:51

0 Answers0