TypeScript: Typ-Deklarationen
13.07.2020, 00:00 Uhr
Deklaratives
Das statische Typsystem von TypeScript funktioniert am besten, wenn geeignete Typ-Informationen vorliegen. Das ist aber bei reinem JavaScript-Code nicht immer der Fall.
Eine der größten Stärken des Typsystems von TypeScript ist, dass es rein optional ist: Im Zweifelsfall kann man den Compiler stets dadurch zum Schweigen bringen, dass man eine Variable als any deklariert. Das heißt, dass sie jeden beliebigen Typ aufnehmen kann, allerdings verliert man so auch jegliche Unterstützung von Seiten des Editors beziehungsweise der IDE. Da any alles Mögliche darstellen kann, lässt sich keine vernünftige Hilfestellung mehr leisten.
Aus persönlicher Erfahrung
Als ich mich im Juli 2019 zum ersten Mal mit TypeScript beschäftigt habe, habe ich mir eine kleine Funktion gesucht, die ich testweise migrieren wollte. Meine Wahl fiel auf eine interne Funktion namens getIpAddresses eines größeren Projekts, der man entweder einen Hostnamen oder eine IP-Adresse übergeben konnte und die in jedem Fall eine IP-Adresse zurückgab – praktisch zum Normalisieren des übergebenen Wertes. Der Code für die Funktion ist simpel:
import { ip } from './ip';
import { promises as dns, LookupAddress } from 'dns';
import { isEqual, uniqWith } from 'lodash';
const { lookup } = dns;
const getIpAddresses = async function (
hostOrIp: string
): Promise<{ address: string; family: number }[]> {
if (ip.is(hostOrIp)) {
return [{ address: hostOrIp, family: ip.getFamily(
hostOrIp) }];
}
const addresses = await lookup(hostOrIp, { all: true });
const mappedAddresses =
addresses.map((address): LookupAddress => ({
address: address.address,
family: address.family
}));
const uniqueAddresses =
uniqWith(mappedAddresses, isEqual);
return uniqueAddresses;
};
export { getIpAddresses };
import { ip } from './ip';
import { promises as dns, LookupAddress } from 'dns';
import { isEqual, uniqWith } from 'lodash';
const { lookup } = dns;
const getIpAddresses = async function (
hostOrIp: string
): Promise<{ address: string; family: number }[]> {
if (ip.is(hostOrIp)) {
return [{ address: hostOrIp, family: ip.getFamily(
hostOrIp) }];
}
const addresses = await lookup(hostOrIp, { all: true });
const mappedAddresses =
addresses.map((address): LookupAddress => ({
address: address.address,
family: address.family
}));
const uniqueAddresses =
uniqWith(mappedAddresses, isEqual);
return uniqueAddresses;
};
export { getIpAddresses };
Bemerkenswert daran war, dass der Code zuvor bereits mehrere Jahre anstandslos seinen Dienst verrichtet hatte, doch nun bemängelte der TypeScript-Compiler den Aufruf von map innerhalb der Funktion: Hier gäbe es Typ-Konflikte. Da das wie gesagt mein allererster Kontakt mit TypeScript war, bin ich davon ausgegangen, dass der Fehler bei mir läge, und habe mehrere Stunden damit verbracht, ihn zu suchen.
Irgendwann kam ich darauf, dass das Promise-Interface des dns-Moduls von Node.js noch relativ jung war und die Typen für die darin enthaltene lookup-Funktion eventuell falsch sein könnten. Tatsächlich stellte sich genau das heraus, wie das zugehörige Issue bei Definitely Typed [9] zeigt. Gelernt habe ich daraus, dass man dem Compiler nicht blind vertrauen sollte und immer in Betracht ziehen muss, dass der Fehler auch an anderer Stelle liegen könnte, als man zunächst annimmt.
Jetzt 1 Monat kostenlos testen!
Sie wollen zukünftig auch von den Vorteilen eines plus-Abos profitieren? Werden Sie jetzt dotnetpro-plus-Kunde.
- + Digitales Kundenkonto,
- + Zugriff auf das digitale Heft,
- + Zugang zum digitalen Heftarchiv,
- + Auf Wunsch: Weekly Newsletter,
- + Sämtliche Codebeispiele im digitalen Heftarchiv verfügbar