typescript - Begränsa gränssnittets typparameter i metod
Jag försöker förmedla att en metod bara är meningsfull när typen på dess interface uppfyller ett visst krav. Här är ett (icke-kompilerande) exempel:
interface Array<T> {
fold<B>(base: B, f: (acc: B, e: T) => B): B
sum(): T is number
}
Array.prototype.fold = function(base, f) {
let result = base
for (let i = 0; i < this.length; i++)
result = f(result, this[i])
return result
}
Array.prototype.sum = function() {
return this.fold(0, (acc, e) => acc + e)
};
[1, 'a', 3].sum() //? 1a3 <-- should be an error!
Här försökte jag förmedla att sum bara är meningsfullt när T extends number.
Svar #1
Du har rätt idé, bara fel syntax.
Så här skriver du det.
interface Array<T> {
sum(this: number[]): number;
}
Observera hur vi använde typen this som är en syntetisk parameter och inte ändrar funktionens aritet. Den syntax du försökte använda, även om det är ett intressant gissning, används för ett annat syfte, nämligen typvakter.
Den intressanta delen är att typeannoteringen på this har företräde framför typen på gränssnittet. Du kan också deklarera en generisk parameter, applicera den på this, och sätta begränsningar på T så att den också kan kompositioneras. Det finns en mängd flexibilitet.
Här är en intressant som kombinerar både gränssnittstypen och förfinar den med this
interface Array<T> {
flatten(this: T[][]): T[];
}
