Reputation: 997
Let's say I have the following interface:
interface Option {
options: string[];
symbolOption: string;
}
How can I enforce that the symbolOption
must be included in the options
array?
This will be OK:
const option: Option = {
options: ['a', 'b'],
symbolOption: 'a' // ✅ OK
};
But this will not be OK:
const option: Option = {
options: ['a', 'b'],
symbolOption: 'c' // 🔴 `c` is not included in the `options` list.
};
Upvotes: 1
Views: 64
Reputation: 141512
This works (playground) though I am not sure whether providing the generic arguments of 'a' | 'b'
will suit your requirement or not.
interface Option<T> {
options: T[];
symbolOption: T;
}
// This will be OK:
const optionGood: Option<'a' | 'b'> = {
options: ['a', 'b'],
symbolOption: 'a' // ✅ OK
};
// But this will not be OK:
const optionBad: Option<'a' | 'b'> = {
options: ['a', 'b'],
symbolOption: 'c' // 🔴 `c` is not included in the `options` list.
};
Here is another alternative courtesy of jcalz
(playground).
interface OptionConstraint<
T extends string,
O extends OptionConstraint<T, O>
> {
options: T[];
symbolOption: O["options"][number];
}
const asOption = <T extends string, O extends OptionConstraint<T, O>>(o: O) =>
o;
// This will be OK:
const optionGood = asOption({
options: ["a", "b"],
symbolOption: "a" // ✅ OK
});
// But this will not be OK:
const optionBad = asOption({
options: ["a", "b"],
symbolOption: "c" // 🔴 `c` is not included in the `options` list.
});
Upvotes: 1
Reputation: 58182
If I understand what you are asking, it would be as simple as:
interface Option {
options: Array<'a'|'b'>;
symbolOption: string;
}
Edit Edit based on comments.
What you are asking isn't possible, TypeScript is largely a compile type check, you can't have a dynamic type value to represent an interface type.
Have a read of How to check the object type on runtime in TypeScript? to understnad what can and can't be done at runtime
Upvotes: 0