Let's say we have the following interface:
interface I<A extends string, B extends string> {
a: A,
b: B,
c: `${A} ${B}`
}
I want to make a function which makes an array of I and validates its types so that
makeArr([
{
a: "1",
b: "2",
c: <- it should have type "1 2" | "3 4"
},
{
a: "3",
b: "4",
c: <- it should have type "1 2" | "3 4"
}
])
I have already tried implementing it like this:
type Arr<A extends string, B extends string> = I<A, B>[]
function makeArr<A extends string, B extends string>(arr: Arr<A, B>) {
return arr
}
However, the c property still accepts any string
makeArr([
{
a: "1",
b: "2",
c: "this does not work"
},
{
a: "3",
b: "4",
c: "whatever "
}
])
It does a little bit better when you specify the types explicitly, but c accepts some wrong types anyway
makeArr<"1" | "3", "2" | "4">([
{
a: "1",
b: "2",
c: "3 2"
},
{
a: "3",
b: "4",
c: "1 4"
}
])
I also wouldn't like to specify it explicitly, because those arrays may be very long
Edit: Thanks to aleksxor's answer I managed to implement it, however the types must be specified explicitly Playground Link