Reputation: 637
I have an interface containing two properties, and I want that the second property type to be equal to the first property, the first property type being a string for example.
interface Argument {
type: any;
allowedValues: [insert way to infer type from `type` property]
}
const a: Argument = {
type: 'string',
allowedValues: 'test', // only because `type` property is a string
}
type
property can be anything but allowedValues should be the same type as type
(or an array of it)
Upvotes: 1
Views: 684
Reputation: 330086
There is no specific concrete type in TypeScript corresponding exactly to what you consider a valid argument
, where the allowedValues
property must have the same type as the type
property. If you want to be able to represent this at all in TypeScript, you'll probably need to think of it as more of a generic constraint, and use a helper function instead of a type annotation to validate that any given candidate value conforms to the constraint:
interface Argument<T> {
type: T;
allowedValues: T
}
const asArgument = <T,>(a: Argument<T>) => a;
Here we are making a generic type Argument<T>
that keeps track of the type of the type
and allowedValues
properties being correlated. You can test it out:
const a = asArgument({
type: 'string',
allowedValues: 'test', // okay
});
asArgument({
type: 123,
allowedValues: 456
}); // okay
asArgument({
type: 'string',
allowedValues: 456 // error! Type 'number' is not assignable to type 'string'
})
If you try to give allowedValues
a value of a different type from that of type
, you get an error.
Note that by making your Argument
type generic, you'll need to drag around the extra generic type parameter T
wherever you need to keep track of this constraint. I magine changing all mentions of Argument
to Argument<T>
and adding T
to whatever scope is necessary. So I'd suggest only using this constraint for initial validation of developer-submitted arguments, and then widen it to a concrete type like Argument<any>
for use in internal code that assumes it's already been validated.
Upvotes: 1