1

Is it possible to get the type of an object property using a variable? I.e. using the string x, I would like to get string type and using the string y I want to get number type.

type Obj = Readonly<{
  x: string,
  y: number
}>

const obj = {
  x: 'abc',
  y: 123
}

type TypeOfX = Obj['x']; // this works fine and returns string
type TypeOfY = Obj['y']; // this works fine and returns number

type Property = keyof Obj;
const property: Property = 'x';
// error here
type TypeOfObjProperty = Obj[property];

The errors are:

Type 'any' cannot be used as an index type.(2538)
'property' refers to a value, but is being used as a type here. Did you mean 'typeof property'?(2749)
Exported type alias 'TypeOfObjProperty' has or is using private name 'property'.(4081)
7
  • 3
    You can't use runtime information (the value of property) to define a compile-time construct (a type). You could do const property = "x"; and then Obj[typeof property], because typeof property would be the string literal type "x". But you can't do it with the value of the variable, just its type. Commented Aug 16, 2021 at 13:10
  • @T.J.Crowder if property is of type keyof Obj and Obj is readonly, isn't it known at compile time that the value can only be x or y? Commented Aug 16, 2021 at 13:13
  • If you do type TypeOfObjProperty = Obj[typeof property]; it will correctly infer the type as string or number depending on the property variable. Is that what you want? Commented Aug 16, 2021 at 13:18
  • Yes. As the error message says, if you use typeof property with this specific example, it'll work (because TypeScript's flow analysis tells it that property is of type "x"). If TS couldn't determine that from flow analysis, the type you'd get would be string | number because the type of property is "x" | "y" (playground). But Obj[property] is using property as a value, not as a type. Commented Aug 16, 2021 at 13:18
  • 1
    I think my only option is to have explicit logic for each key like if (key === 'a' || key === 'b') {, rather than working out the type of the key which typescript can't know because it's not there at runtime. Commented Aug 16, 2021 at 13:25

1 Answer 1

2

While Obj[property] only works as a type when property is a type, you can use generics and extends to simulate this, at least on the function level:

type Obj = Readonly<{
  x: string,
  y: number
}>

function f<Property extends keyof Obj, TypeOfObjProperty extends Obj[Property]>
  (prop: Property, value: TypeOfObjProperty) {
    // TypeOfObjProperty is the type Obj[prop]
}

Playground link

Depending on what you're doing, this may give you the type TypeOfObjProperty that you need.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.