13

Can I check if a string exists as an interface key

interface list {
    one: string
    two: string
}

const myNumber = "one"

How do I check if myNumber value is an interface key

2
  • What are you trying to accomplish? What do you want to happen if the value is in the interface, or if it's not in the interface? Do you want to provoke a compile-time error when it's not in the interface, or something like that? Commented Oct 27, 2020 at 23:54
  • 1
    I have an object literal with keys in addition to those of the 'list' interface and would like to filter that Object with those keys only in the 'list' interface Commented Oct 27, 2020 at 23:59

3 Answers 3

6

The type of Typescript is not a value.

Therefore, operation of Javascript is impossible.

However, in the example, the type can be set so that myNumber is the type corresponding to the key.

interface list {
    one: string
    two: string
}

const myNumber: keyof list = "one"; // myNumber allow only "one" or "two";
Sign up to request clarification or add additional context in comments.

Comments

4

To do this, you'll need to have something that lets you get the key of the interface at runtime. An interface does not exist at runtime - it's purely a TypeScript construct, so it doesn't exist in emitted code.

Make an array that contains the keys, declare it as const so it doesn't get automatically type-widened, and then you'll be able to turn it into the List type. Then you'll have both a type and a runtime array that you can use an .includes check on:

const listKeys = ['one', 'two'] as const;
type List = Record<typeof listKeys[number], string>;

// ...

const obj = {
    one: 'one',
    two: 'two',
    three: 'three'
};
// Transformation to string[] needed because of an odd design decision:
// https://github.com/Microsoft/TypeScript/issues/26255
const newObj = Object.fromEntries(
    Object.entries(obj).filter(
        ([key]) => (listKeys as unknown as string[]).includes(key)
    )
);

Playground link

Comments

0

You can use typeguard function like this, if you have object which implements this interface:

interface List {
    one: string
    two: string
}

const list: List = {
    one: "some one"
    two: "some two"
}

function isListKey(value: string, list: IList): value is keyof List {
    return Object.keys(list).includes(value);
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.