Hur kan jag tilldela en ospecificerad generisk funktion till en variabel i TypeScript?
Hur kan jag tilldela en oparametriserad generisk funktion till en variabel?
I följande exempel, överväg mitt försök att skapa funktionen areArraysShallowlyEqual genom att göra en sammansättning av generiska funktioner och tilldela resultatet av sammansättningen till en variabel:
export function areNullablesEqualOver<a>(areEqual: (one: a, another: a) => boolean)
:(one: a, another: a) => boolean {
return function(one, another) {
if (one == null) {
if (another == null) {
return true;
} else {
return false;
}
} else {
if (another == null) {
return false;
} else {
return areEqual(one, another);
}
}
};
};
export function areArraysEqualOver<a>(areEqual: (one: a, another: a) => boolean)
: (one: a[], another: a[]) => boolean {
return function (ones, anothers) {
var length = ones.length;
if (length !== anothers.length) return false;
for (var index = 0; index < length; index++) {
if (areEqual(ones[index], anothers[index])) continue;
return false;
}
return true;
}
}
export function areSame<a>(one: a, another: a): boolean {
return one === another;
}
// PROBLEM:
export var areArraysShallowlyEqual<a> = areNullablesEqualOver<a>(areArraysEqualOver(areSame));
Svar #1
Du skulle kunna göra detta med hjälp av en generisk klass. Detta är inte exakt samma som det du gör eftersom du skulle behöva instansiera klassen med typargumentet, snarare än att skicka ett typargument till de enskilda funktionerna - men eftersom du inte kan skicka ett typargument till en variabel är din föreslagna implementation inte möjlig.
Gränssnitten är inte obligatoriska, du kan upprepa typannoteringen genomgående istället, men de hjälper till att skilja mellan array- och icke-arrayvariationerna.
areArraysEqualOver och areNullablesEqualOver har bytts plats i egenskapen areArraysShallowlyEqual - detta beror på att metoden areArraysEqualOver inte returnerar en typ som är kompatibel med de andra signaturerna eftersom den returnerar en array-jämförare och alla andra metoder accepterar en icke-array-jämförare.
interface EqualityFunction<T> {
(one: T, another: T) : boolean;
}
interface ArrayEqualityFunction<T> {
(one: T[], another: T[]) : boolean;
}
class Example<a> {
areNullablesEqualOver(areEqual: EqualityFunction<a>) : EqualityFunction<a> {
return function(one, another) {
if (one == null) {
if (another == null) {
return true;
} else {
return false;
}
} else {
if (another == null) {
return false;
} else {
return areEqual(one, another);
}
}
};
}
areArraysEqualOver(areEqual: EqualityFunction<a>) : ArrayEqualityFunction<a> {
return function (ones, anothers) {
var length = ones.length;
if (length !== anothers.length) return false;
for (var index = 0; index < length; index++) {
if (areEqual(ones[index], anothers[index])) continue;
return false;
}
return true;
}
}
areSame(one: a, another: a): boolean {
return one === another;
}
areArraysShallowlyEqual = this.areArraysEqualOver(this.areNullablesEqualOver(this.areSame));
}
Uppringningskoden ser ut så här:
var example = new Example<string>();
example.areArraysShallowlyEqual(['a', 'b'], ['a', 'b']); // true
example.areArraysShallowlyEqual(['a', 'b'], ['a', 'c']); // false
