arthurakay
arthurakay

Reputation: 5651

Typescript: declare a parameter or property as one of the keys in a known object

I'm fairly new to TypeScript, and I've been trying to refactor some code.

Considering I have an object defined as such:

const Operators = {
    equal: '=',
    not_equal: '!=',
    less: '<',
    less_or_equal: '<=',
    greater: '>',
    greater_or_equal: '>=',
    contains: '~'
};

And then I have a class defined as such:

class Query {
    // I want to limit this to the keys defined in Operator
    operator: string;

    constructor(operator: string) {
        this.operator = operator;
    }

    getOperatorValue: string {
        return Operators[this.operator];
    }
}

How can I enforce that the parameter "operator" be one of the keys of Operators?

I get the following error against the line inside getOperatorValue():

Error: TS7017:Element implicitly has an 'any' type because type '{ equal: string; not_equal: string; less: string; less_or_equal: string; greater: string; greater...' has no index signature.

This is using Typescript 2.4.2.

Upvotes: 1

Views: 158

Answers (1)

ssube
ssube

Reputation: 48257

You might be looking for the keyOf operator, introduced in 2.1 and documented with index types. Simply, function foo<T>(bar: T, key: keyof T) ensure that key will always be a known key from T. It provides an easy way to type-safely use string indexers, among other uses in the type system.

The docs show examples of using keyOf to implement a type-safe Partial class:

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}
type Partial<T> = {
    [P in keyof T]?: T[P];
}

Upvotes: 2

Related Questions