'Typescript dynamic type based on array value

What is the correct interface IMyClass which would fulfill the requirements?

interface IMyClass  {
    params: any
    chooseParam: Function
}

class MyClass implements IMyClass {
    params = ['min', 'max']

    chooseParam = (oneOfParams) => {   
        return oneOfParams === "min" ? "something" : "something2" // <- I want to intellisense to say me that oneOfParams = "min" | "max"
    }
}

//usage
const a = new MyClass()
a.chooseParam("min")    // <- I want to intellisense here "min" | "max"

TS playground



Solution 1:[1]

Does params have to part of the interface? Looks like it's just an argument to chooseParam. I'd do something like this:

enum ParamOption {
    Min = 'min',
    Max = 'max'
}

interface IMyClass  {
    chooseParam: Function
}

class MyClass implements IMyClass {

    chooseParam = (oneOfParams: ParamOption) => {
        return oneOfParams === ParamOption.Min ? true : false
    }
}

//usage
const a = new MyClass()
a.chooseParam(ParamOption.Min)

Solution 2:[2]

COnsider this example:

interface IMyClass {
    params: readonly [string, string]
    chooseParam: Function
}

class MyClass implements IMyClass {
    params = ['min', 'max'] as const

    chooseParam = (oneOfParams: this['params'][number]) => {
        return oneOfParams === "min" ? true : false
    }
}

const a = new MyClass()

a.chooseParam('max') 

Playground

this['params'][number] - obtains a union of all values in params

Is there any way to define the type of function chooseParam inside interface IMyClass instead of Function type

Sure, if you want to type a function, please see here and here. In general, your interface should look like this:

type Tuple = ['min', 'max']

interface IMyClass {
    params: Tuple
    chooseParam: (param: Tuple[number]) => boolean;
}

class MyClass implements IMyClass {
    params: Tuple = ['min', 'max']

    chooseParam = (oneOfParams: Tuple[number]) => {
        return oneOfParams === "min" ? true : false
    }
}

const a = new MyClass()

a.chooseParam('max') 

However, it can be better. As far as I understood ['min', 'max'] is a static value which is not changed across app life cycle. If it is true it might be a good idea to move params out of a scope of MyClass.

const Params = ['min', 'max'] as const;

type Params = typeof Params;

interface IMyClass {
    chooseParam: (param: Params[number]) => boolean;
}

class MyClass implements IMyClass {
    chooseParam = (oneOfParams: Params[number]) => {
        return oneOfParams === "min" ? true : false
    }
}

const a = new MyClass()

a.chooseParam('max') 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pew007
Solution 2