Programmiersprache TypeScript 4.9 prĂĽft Voraussetzungen mit satisfies-Operator
Neben dem neuen Operator, der Bedingungen festlegt, ohne Typen durch zusätzliche Angaben einzuschränken, passt die Beta von TypeScript 4.9 den in-Operator an.
Microsoft hat die erste Beta von TypeScript 4.9 veröffentlicht. Der JavaScript-Aufsatz erhält im aktuellen Release mit satisfies
einen neuen Operator, um unterschiedliche Vorgaben fĂĽr Expressions festzulegen. AuĂźerdem bietet der in
-Operator klare Typzuweisungen fĂĽr den SchlĂĽssel und das Objekt.
ErfĂĽllte Voraussetzungen
Der neue Operator satisfies
dient für unterschiedliche Typprüfungen in Ausdrücken. Er kann für Properties sowohl den passenden Namen als auch den passenden Typ als Bedingung festlegen, ohne dabei eine strikte Typvorgabe in der Deklaration zu erfordern. Das zugehörige Issue trägt den Titel "'satisfies' operator to ensure an expression matches some type".
Unter anderem lässt sich festlegen, dass Properties den passenden Namen haben, ohne dabei einen festen Typ vorzugeben wie in folgendem Beispiel aus dem Issue:
type Keys = 'a' | 'b' | 'c' | 'd';
const p = {
a: 0,
b: "hello",
c: true
// Fehler: 'd' aus 'Keys' fehlt
} satisfies Record<Keys, unknown>;
Die Vorgabe lässt sich über Partial
flexibler gestalten: Es legt fest, dass die Namen der Properties zwar aus der Bedingung stammen, aber nicht vollständig vorhanden sein müssen. Mit dem Zusatz würde obiges Beispiel somit keinen Fehler auslösen, aber folgendes:
type Keys = 'a' | 'b' | 'c' | 'd';
const p = {
a: 0,
b: "hello",
x: 8 // Fehler: 'x' ist nicht in 'Keys' vorhanden
} satisfies Partial<Record<Keys, unknown>>;
Mit satisfies
lässt sich zudem unter anderem umgekehrt festlegen, dass die Properties beliebige Namen tragen dürfen, ihre Werte aber einem bestimmten Typ entsprechen müssen. Zu den weiteren Bedingungen gehört das Implementieren eines bestimmten Interfaces:
type Movable = {
move(distance: number): void;
};
const car = {
start() { },
move(d) {
// d: number
},
stop() { }
} satisfies Moveable;
Passende Properties fĂĽr den in-Operator
Im Zusammenspiel mit dem JavaScript-Operator in
setzt TypeScript 4.9 auf ein weniger striktes Type Narrowing als bisher. Folgendes Codebeispiel aus dem TypeScript-Blog fĂĽhrte bisher zu einem Fehler, da TypeScript packageJSON
als object
zugeordnet hat, das die Property name
nicht enthält:
interface Context {
packageJSON: unknown;
}
function tryGetPackageName(context: Context) {
const packageJSON = context.packageJSON;
// Check to see if we have an object.
if (packageJSON && typeof packageJSON === "object") {
// Check to see if it has a string name property.
if ("name" in packageJSON &&
typeof packageJSON.name === "string") {
// ~~~~
// error! Property 'name' does not exist on type 'object.
return packageJSON.name;
// ~~~~
// error! Property 'name' does not exist on type 'object.
}
}
return undefined;
}
Mit dem aktuellen Release stellt TypeScript fĂĽr den Ausdruck key in obj
fĂĽr existierende SchlĂĽssel sicher, dass der Wert fĂĽr key
entweder ein String, eine Zahl oder ein Symbol sein muss (string | number | symbol
) und obj
vom Typ object
ist. Damit funktioniert obiges Codebeispiel fehlerfrei.
Kein Vergleich fĂĽr keine Zahl
FĂĽr den Spezialwert NaN
, der für Not a Number, also kein Zahlenwert steht, gelten Sonderregeln – nicht nur für TypeScript und JavaScript, sondern für alle Sprachen, die Gleitkommazahlen nach IEEE 754 implementieren. Die Spezifikation legt fest, dass alle Gleichheitschecks zu NaN
false
ergeben. Per Definition gilt dabei auch:
console.log(NaN == NaN) // false
console.log(NaN === NaN) // false
console.log(NaN != NaN) // true
console.log(NaN !== NaN) // true
NaN
ist also auch ungleich NaN
. Das kann zu einem Anfängerfehler führen, wenn Code die Prüfung auf NaN
mit einem !=
durchführt. Daher verbietet TypeScript ab sofort Gleich- und Ungleichheitsprüfungen auf Not a Number und schlägt stattdessen den Einsatz der Methode Number.isNaN()
vor:
function validate(someValue: number) {
return someValue !== NaN;
// ~~~~~~~~~~~~~~~~~
// error: This condition will always return 'true'.
// Did you mean '!Number.isNaN(someValue)'?
}
Weitere Neuerungen in Version 4.9 lassen sich dem TypeScript-Blog entnehmen. Ende Oktober soll der erste Release Candidate erscheinen und das endgĂĽltige Release steht fĂĽr den 15. November auf dem Plan.
(rme)