check if object has key in Typescript and use that key
Asked Answered
B

2

19

I have the following code:

let show = {
    createTag: false,
    updateFeature: false,
    createFeatureGroup: false,
    deleteFeature: false,
    deleteCycle: false,
};

And I'm getting a value from the querystring that I want to match agains the keys of show.

The following code works ok, but I want a way to let Typescrpt infer it and avoid having to issue the cast:

const showDialog = $page.query.get('show') || '';

if (showDialog && showDialog in show) {
    // I want to get rid of the "<keyof typeof show>" cast
    show[<keyof typeof show>showDialog] = true; 
}

I though that just issueing showDialog in show typescript would know that inside that if showDialog is a key of show, but it doesn't seem to be the case.

Black answered 5/10, 2021 at 22:36 Comment(1)
in narrowing only works with string literals: typescriptlang.org/docs/handbook/2/…Splasher
S
9

You can create a type guard:

function isValidParam(k: string): k is keyof typeof show {
  return k in show;
}

const showDialog = $page.query.get('show') || '';

if (isValidParam(showDialog)) {
    show[showDialog] = true; 
}

but you decide if it's worth it. I'd probably just keep the cast, personally.

Search answered 5/10, 2021 at 23:28 Comment(0)
V
17

The type guard presented by @paolostyle is very specific to the show object. The following snippet is more generic and can be used for any key in any object:

export function isKeyOfObject<T>(
  key: string | number | symbol,
  obj: T,
): key is keyof T {
  return key in obj;
}
Verner answered 22/1, 2022 at 8:11 Comment(1)
I had to change this to isKeyOfObject<T extends object> — probably due to Typescript version differences?Layman
S
9

You can create a type guard:

function isValidParam(k: string): k is keyof typeof show {
  return k in show;
}

const showDialog = $page.query.get('show') || '';

if (isValidParam(showDialog)) {
    show[showDialog] = true; 
}

but you decide if it's worth it. I'd probably just keep the cast, personally.

Search answered 5/10, 2021 at 23:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.