1
type Test1 = {
  srn1: number
}

type Test2 = {
  srn2: number
}

type Test3 = {
  srn3: number
}

const test1: Test1 = { srn1: 1 };
const test2: Test2 = { srn2: 2 };
const test3: Test3 = { srn3: 3 };

function incrementSrn(prop: string, obj: Test1 | Test2 | Test3): void {
  if (obj[prop] !== undefined) obj[prop] += 1;
}

incrementSrn('srn1', test1);

I get errors:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Test1 | Test2 | Test3'.
  No index signature with a parameter of type 'string' was found on type 'Test1 | Test2 | Test3'.
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Test1 | Test2 | Test3'.
  No index signature with a parameter of type 'string' was found on type 'Test1 | Test2 | Test3'.

I can add key signature in the types of course like

[key: string]: number

But I don't want my types Test1, Test2 and Test3 have any other properties they have.

Thank you for your help in advance.

Subrato Pattanaik
  • 5,331
  • 6
  • 21
  • 52
  • [Element implicitly has an 'any' type because expression of type 'string' can't be used to index](https://stackoverflow.com/q/57086672) – VLAZ Aug 24 '21 at 15:35

1 Answers1

0

You need to write a generic function to keep the parameters within the constraints, like...

function incrementSrn<P extends string>(prop: P, obj: { [x in P]: number }): void {
  if (obj[prop] !== undefined) obj[prop] += 1;
}

incrementSrn('srn1', { srn1: 1 }); // OK
incrementSrn('srn2', { srn1: 1 }); // error, srn2 field does not exist
incrementSrn('srn2', { srn1: 1, srn2: '' }); // error, srn2 is not of type number
T.D. Stoneheart
  • 811
  • 4
  • 7