typescript - Skapa arrayer av generiska gränssnitt
Låt oss säga att vi har följande gränssnitt:
interface I<A extends string, B extends string> {
a: A,
b: B,
c: `${A} ${B}`
}
Jag vill skapa en funktion som gör en array av I och validerar dess typer så att
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"
}
])
Jag har redan försökt implementera det så här:
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
}
Dock accepterar c-egendomen fortfarande vilken sträng som helst
makeArr([
{
a: "1",
b: "2",
c: "this does not work"
},
{
a: "3",
b: "4",
c: "whatever "
}
])
Det fungerar lite bättre när du specificerar typerna uttryckligen, men c accepterar ändå några felaktiga typer
makeArr<"1" | "3", "2" | "4">([
{
a: "1",
b: "2",
c: "3 2"
},
{
a: "3",
b: "4",
c: "1 4"
}
])
Jag skulle inte heller vilja specificera det uttryckligen, eftersom de där arrayerna kan vara väldigt långa
Redigera: Tack vare aleksxors svar lyckades jag implementera det, men typerna måste anges uttryckligen Playground-länk
Svar #1
Jag tror att det måste finnas ett mer elegant sätt. Men här är mitt försök att implementera en sådan kontroll:
type I<T extends { a: string, b: string }> = T extends {
a: T['a'],
b: T['b'],
c: `${T['a']} ${T['b']}`
} ? T : never
function makeArr<T extends { a: string, b: string }>(arr: readonly [...I<T>[]]) {
return arr
}
makeArr([
{
a: "1",
b: "2",
c: "doesn't pass"
},
{
a: "3",
b: "4",
c: "3 4"
}
])
lekplatslänk
