In TypeScript it’s possible to set the type of a parameter using literals, for example:
type Allowed = "fizz" | "buzz";
class FizzBuzz {
public identity(x: Allowed) {
return x;
}
}
This means the following snippet of code will give an error even before the code is run:
let fizzBuzz = new FizzBuzz()
fizzBuzz.identity("not-fizz-not-buzz");
In my scenario, however, the literals are not know when the class is defined but they are known when the class is used to instantiate an object. In other words, they are expected as a parameter to the constructor itself. For example:
class FizzBuzz {
constructor(allowed: string[]) {
this.allowed = allowed;
}
public identity(x: this.allowed) {
return x;
}
}
let fizzBuzz = new FizzBuzz(["fizz", "buzz"])
I would like my code to still benefit from TypeScript so that if my next line is fizzBuzz.identity("not-fizz-not-buzz");
I see an error even before the code is executed and should see the autocomplete suggestions.
2
Answers
In your second code snippet, you can see the autocomplete suggestions at design time, while editing the code. But how can you expect to see autocomplete suggestions for something that is known only at runtime, when there is not necessarily any code editor open?
The best I can imagine is logging an error that contains the suggestions, and you don’t even need Typescript for that:
When this is run, it logs the following error:
(Added after reading apokryfos’s answer:) It matters when exactly the literals are known. You write "when the class is used to instantiate an object", does this mean
new FizzBuzz(getListOfLiterals())
?In the first case, apokryfos’s method is preferable. But it cannot handle the second case.
In this case you could use generics:
This will not be possible if the values of
allowed
are not known at compile timeIf you are concerned about the duplication then you can let TS do some of the work for you: