Reputation: 454
Is there a way to detect duplicate values from properties in a TypeScript interface? ex:
interface Props {
foo: string;
bar: string;
}
let x : Props = {
foo: 'hello world',
bar: 'hello world'
}
// show TypeScript warning for foo and bar having the same value
Upvotes: 0
Views: 259
Reputation: 328453
There's no concrete type in TypeScript that represents such a constraint. Instead, you could use a generic type and a helper function to produce values of that type. Like, for example, this:
const asDistinctProps = <F extends string, B extends string>(
props: { foo: F, bar: Exclude<B, F> }
) => props;
Here, asDistinctProps
is a generic function that takes an object with string
-valued foo
and bar
properties. But the type of bar
is constrained so that it cannot be the same value as the foo
type... as long as you're dealing with string literal types and not just string
:
let x = asDistinctProps({
foo: 'hello world',
bar: 'hello world' // error!
});
let y = asDistinctProps({
foo: 'hello world',
bar: 'goodbye cruel world'
}); // okay
So that works the way you want.
Do remember though that the compiler will often widen a string from its literal value to string
, and at that point it's not possible to properly apply the constraint. Here:
let z: string = "hello";
asDistinctProps({foo: z, bar: "goodbye"}); // error!
you are prevented from using asDistinctProps
at all because the foo
property is just string
. And here:
asDistinctProps({ foo: "hello", bar: z }); // no error!
you are not prevented from specifying the same value twice because the compiler does not see string
as conflicting with "hello"
.
So with the above caveats, it's sort of possible. In practice I'd probably make the constraint enforced primarily at runtime and not worry about having the type system involved too much. Okay, hope that helps; good luck!
Upvotes: 1