Hva er TypeScript og hvorfor bør jeg bruke det i stedet for JavaScript?


Hva er TypeScript-språket? Hva kan det gjøre som JavaScript eller tilgjengelige biblioteker ikke kan gjøre, som ville gi meg grunn til å vurdere det?

Svar #1

Jeg skrev opprinnelig dette svaret da TypeScript fortsatt var helt ferskt. Fem år senere er dette en grei oversikt, men se på Lodewijks svar nedenfor for mer dybde

1000 fots utsikt...

TypeScript er et supersett av JavaScript som primært gir valgfri statisk typing, klasser og grensesnitt. En av de store fordelene er å gjøre det mulig for IDEer å gi et rikere miljø for å oppdage vanlige feil mens du skriver koden.

For å få en idé om hva jeg mener, se Microsofts introduksjonsvideo om språket.

For et stort JavaScript-prosjekt kan det å ta i bruk TypeScript resultere i mer robust programvare, samtidig som det fortsatt kan distribueres der en vanlig JavaScript-applikasjon ville kjøre.

Det er åpen kildekode, men du får bare den smarte Intellisense mens du skriver hvis du bruker en støttet IDE. Opprinnelig var dette kun Microsofts Visual Studio (også nevnt i blogginnlegg fra Miguel de Icaza). I dag tilbyr også andre IDEer TypeScript-støtte.

Finnes det andre teknologier som dette?

Det finnes CoffeeScript, men det tjener egentlig et annet formål. Etter min mening gir CoffeeScript lesbarhet for mennesker, men TypeScript gir også dyp lesbarhet for verktøy gjennom sin valgfrie statiske typning (se dette nylige blogginnlegget for litt mer kritikk). Det finnes også Dart, men det er en fullverdig erstatning for JavaScript (selv om det kan generere JavaScript-kode).

Eksempel

Som et eksempel, her er litt TypeScript (du kan leke med dette i TypeScript Playground)

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}  

Og her er JavaScripten den ville produsere

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

Merk hvordan TypeScript definerer typen til medlemsvariabler og klassemetodeparametere. Dette fjernes når det oversettes til JavaScript, men brukes av IDE-en og kompilatoren for å oppdage feil, som å sende en numerisk type til konstruktøren.

Den er også i stand til å utlede typer som ikke er eksplisitt erklært, for eksempel vil den bestemme at greet()-metoden returnerer en streng.

Feilsøking av TypeScript

Mange nettlesere og IDE-er tilbyr direkte feilsøkingsstøtte gjennom sourcemaps. Se dette Stack Overflow-spørsmålet for mer informasjon: Feilsøking av TypeScript-kode med Visual Studio

Vil du vite mer?

Jeg skrev opprinnelig dette svaret da TypeScript fortsatt var helt nytt. Sjekk ut Lodewijks svar på dette spørsmålet for noen mer oppdaterte detaljer.

Svar #2

TypeScript sin relasjon til JavaScript

TypeScript er en typet overgruppe av JavaScript som kompileres til vanlig JavaScript - typescriptlang.org.

JavaScript er et programmeringsspråk som utvikles av ECMAs Technical Committee 39, som er en gruppe mennesker sammensatt av mange forskjellige interessenter. TC39 er et utvalg som ledes av ECMA: en intern standardiseringsorganisasjon. JavaScript har mange forskjellige implementasjoner av mange forskjellige leverandører (f.eks. Google, Microsoft, Oracle, osv.). Målet med JavaScript er å være webens lingua franca.

TypeScript er en superset av JavaScript-språket som har en enkelt åpen kildekode-kompilator og utvikles hovedsakelig av en enkelt leverandør: Microsoft. Målet med TypeScript er å hjelpe til med å oppdage feil tidlig gjennom et typesystem og å gjøre JavaScript-utvikling mer effektiv.

I hovedsak oppnår TypeScript sine mål på tre måter:

  1. Støtte for moderne JavaScript-funksjoner - JavaScript-språket (ikke kjøreren) er standardisert gjennom ECMAScript-standardene. Ikke alle nettlesere og JavaScript-kjørere støtter alle funksjoner i alle ECMAScript-standarder (se denne oversikten). TypeScript tillater bruk av mange av de nyeste ECMAScript-funksjonene og oversetter dem til eldre ECMAScript-mål etter eget valg (se listen over kompilermål under --target-kompilatoralternativet). Dette betyr at du trygt kan bruke nye funksjoner, som moduler, lambda-funksjoner, klasser, spread-operatoren og destrukturering, samtidig som du forblir bakoverkompatibel med eldre nettlesere og JavaScript-kjørere.

  2. Avansert typesystem - Typesupporten er ikke en del av ECMAScript-standarden og vil sannsynligvis aldri bli det på grunn av den tolkningsbaserte i stedet for kompilert naturen til JavaScript. Typesystemet til TypeScript er utrolig rikt og inkluderer: grensesnitt, enums, hybride typer, generiske typer, union/interseksjonstyper, tilgangsmodifikatorer og mye mer. Den offisielle nettsiden til TypeScript gir en oversikt over disse funksjonene. Typescripts typesystem er på nivå med de fleste andre typede språk og i noen tilfeller muligens enda kraftigere.

  3. Støtte for utviklerverktøy - TypeScripts kompilator kan kjøre som en bakgrunnsprosess for å støtte både inkrementell kompilering og IDE-integrasjon slik at du enklere kan navigere, identifisere problemer, inspisere muligheter og refaktorere kodebasen din.

TypeScripts forhold til andre språk som retter seg mot JavaScript

TypeScript har en unik filosofi sammenlignet med andre språk som kompileres til JavaScript. JavaScript-kode er gyldig TypeScript-kode; TypeScript er en overmengde av JavaScript. Du kan nesten bare endre navn på .js-filene dine til .ts-filer og begynne å bruke TypeScript (se «JavaScript-interoperabilitet» nedenfor). TypeScript-filer kompileres til lesbar JavaScript, slik at tilbakeflytting er mulig, og det er ikke vanskelig å forstå den kompilerte TypeScript-koden. TypeScript bygger på suksessene til JavaScript samtidig som det forbedrer svakhetene.

På den ene siden har du fremtidssikre verktøy som tar moderne ECMAScript-standarder og kompilerer det ned til eldre JavaScript-versjoner, med Babel som den mest populære. På den andre siden har du språk som kan være helt forskjellige fra JavaScript, men som målretter mot JavaScript, som CoffeeScript, Clojure, Dart, Elm, Haxe, Scala.js, og mange flere (se denne listen). Disse språkene, selv om de kan være bedre enn det JavaScript sin fremtid noen gang kan lede til, har en større risiko for ikke å finne nok brukere til at deres fremtid er garantert. Du kan også ha mer problemer med å finne erfarne utviklere for noen av disse språkene, selv om de du finner ofte kan være mer entusiastiske. Samarbeid med JavaScript kan også være litt mer komplisert, siden de er lengre unna det JavaScript faktisk er.

TypeScript sitter mellom disse to ytterpunktene, og balanserer dermed risikoen. TypeScript er ikke et risikabelt valg etter noen standard. Det krever veldig lite innsats å venne seg til hvis du er kjent med JavaScript, siden det ikke er et helt annet språk, har utmerket støtte for JavaScript-interoperabilitet og har sett mye adopsjon nylig.

Valgfri statisk typing og typeinndukasjon

JavaScript er dynamisk typet. Dette betyr at JavaScript ikke vet hvilken type en variabel har før den faktisk blir instansiert under kjøring. Dette betyr også at det kan være for sent. TypeScript legger til typestøtte i JavaScript og fanger opp typefeil under kompilering til JavaScript. Feil som oppstår på grunn av falske antakelser om at en variabel er av en bestemt type, kan bli fullstendig eliminert hvis du spiller kortene dine riktig (hvor strengt du typiserer koden din, eller om du i det hele tatt typiserer koden, er opp til deg).

TypeScript gjør typingen litt enklere og mye mindre eksplisitt ved bruk av typeinferenz. For eksempel: var x="hello" i TypeScript er det samme som var x : string="hello". Typen blir rett og slett inferert fra hvordan den brukes. Selv om du ikke eksplisitt definerer typene, er de fortsatt der for å spare deg fra å gjøre noe som ellers ville resultert i en kjøretidsfeil.

TypeScript er valgfritt typet som standard. For eksempel function divideByTwo(x) { return x/2 } er en gyldig funksjon i TypeScript som kan kalles med enhver type parameter, selv om det å kalle den med en streng åpenbart vil resultere i en runtime-feil. Akkurat som du er vant til i JavaScript. Dette fungerer fordi når ingen type ble eksplisitt tilordnet og typen ikke kunne utledes, som i divideByTwo-eksemplet, vil TypeScript implisitt tilordne typen any. Dette betyr at funksjonens type-signatur automatisk blir function divideByTwo(x : any) : any. Det finnes en kompilatorflagg som forbyr denne oppførselen: --noImplicitAny. Å aktivere dette flagget gir deg en større grad av sikkerhet, men betyr også at du må skrive mer typeinformasjon.

Typer har en kostnad knyttet til seg. Først og fremst er det en læringskurve, og for det andre vil det selvfølgelig koste deg litt mer tid å sette opp en kodebase med riktig streng typing også. Etter min erfaring er disse kostnadene helt verdt det på enhver seriøs kodebase du deler med andre. En stort studie av programmeringsspråk og kodekvalitet på Github antyder at "statisk typede språk, generelt, er mindre feilutsatte enn de dynamiske typene, og at sterk typing er bedre enn svak typing på samme måte".

Det er interessant å legge merke til at denne samme artikkelen finner at TypeScript er mindre feilutsatt enn JavaScript:

For de med positive koeffisienter kan vi forvente at språket er assosiert med, alt annet likt, et større antall feilrettinger. Disse språkene inkluderer C, C++, JavaScript, Objective-C, Php og Python. Språkene Clojure, Haskell, Ruby, Scala og TypeScript har alle negative koeffisienter, noe som antyder at disse språkene er mindre sannsynlige enn gjennomsnittet til å resultere i commits som fikser feil.

Forbedret IDE-støtte

Utviklingsopplevelsen med TypeScript er en stor forbedring over JavaScript. IDE-en blir informert i sanntid av TypeScript-kompilatoren om dens rike typeinformasjon. Dette gir noen store fordeler. For eksempel kan du med TypeScript trygt gjøre refaktoreringer som å gi nytt navn på tvers av hele koden din. Gjennom kodefullføring kan du få hjelpetekst direkte til funksjonene et bibliotek tilbyr. Du trenger ikke lenger å huske dem eller lete dem opp i nettbaserte referanser. Kompilasjonsfeil rapporteres direkte i IDE-en med en rød bølget linje mens du koder. Alt i alt gir dette en betydelig produktivitetsgevinst sammenlignet med å jobbe med JavaScript. Man kan bruke mer tid på å kode og mindre tid på å feilsøke.

Det finnes et bredt utvalg av IDE-er som har utmerket støtte for TypeScript, som Visual Studio Code, WebStorm, Atom og Sublime.

Strenge nullsjekker

Kjøretidsfeil av typen cannot read property 'x' of undefined eller undefined is not a function skyldes ofte feil i JavaScript-kode. Ferdig konfigurert reduserer TypeScript allerede sannsynligheten for at denne typen feil oppstår, siden man ikke kan bruke en variabel som ikke er kjent for TypeScript-kompilatoren (med unntak av egenskaper til any-typede variabler). Det er likevel mulig å ved en feil bruke en variabel som er satt til undefined. Med versjon 2.0 av TypeScript kan man imidlertid eliminere denne typen feil helt gjennom bruk av ikke-nullbare typer. Dette fungerer som følger:

Med streng nullsjekk aktivert (--strictNullChecks kompilatorflag) vil TypeScript-kompilatoren ikke tillate at undefined blir tildelt en variabel med mindre du eksplisitt erklærer at den kan være nullbar. For eksempel vil let x : number=undefined resultere i en kompilasjonsfeil. Dette passer perfekt med typeteori siden undefined ikke er et tall. Man kan definere x som en summetype av number og undefined for å rette dette: let x : number | undefined=undefined.

Når en type er kjent for å kunne være nullbar, det vil si at den er av en type som også kan ha verdien null eller undefined, kan TypeScript-kompilatoren avgjøre gjennom kontrollflytbasert typeanalyse om koden din trygt kan bruke en variabel eller ikke. Med andre ord, når du sjekker om en variabel er undefined for eksempel gjennom en if-setning, vil TypeScript-kompilatoren slutte at typen i den grenen av koden din sin kontrollflyt ikke lenger er nullbar, og derfor kan brukes trygt. Her er et enkelt eksempel:

let x: number | undefined;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.

Under Build 2016-konferansen ga TypeScript-samedesigner Anders Hejlsberg en detaljert forklaring og demonstrasjon av denne funksjonen: video (fra 44:30 til 56:30).

Kompilasjon

For å bruke TypeScript trenger du en byggeprosess for å kompilere til JavaScript-kode. Byggeprosessen tar vanligvis bare et par sekunder, avhengig av størrelsen på prosjektet ditt. TypeScript-kompilatoren støtter inkrementell kompilering (--watch kompilatorflagg) slik at alle påfølgende endringer kan kompilere med større hastighet.

TypeScript-kompilatoren kan legge inn kildekartinformasjon direkte i de genererte .js-filene eller opprette separate .map-filer. Kildekartinformasjon kan brukes av feilsøkingsverktøy som Chrome DevTools og andre IDE-er for å knytte linjene i JavaScript til de som genererte dem i TypeScript. Dette gjør det mulig for deg å sette brytepunkter og inspisere variabler under kjøretid direkte på TypeScript-koden din. Kildekartinformasjon fungerer ganske bra, den har eksistert lenge før TypeScript, men feilsøking av TypeScript er generelt ikke like godt som når man bruker JavaScript direkte. Ta for eksempel this-nøkkelordet. På grunn av de endrede semantikkene for this-nøkkelordet rundt closures siden ES2015, kan this faktisk eksistere under kjøring som en variabel kalt _this (se dette svaret). Dette kan forvirre deg under feilsøking, men er vanligvis ikke et problem hvis du kjenner til det eller inspiserer JavaScript-koden. Det bør bemerkes at Babel lider av akkurat samme type problem.

Det finnes noen få andre triks TypeScript-kompilatoren kan gjøre, som å generere avskjæringskode basert på dekoratører, generere modulinnlastingskode for forskjellige modulsystemer og analysere JSX. Du vil imidlertid sannsynligvis trenge et byggverktøy i tillegg til TypeScript-kompilatoren. For eksempel, hvis du vil komprimere koden din, må du legge til andre verktøy i byggeprosessen for å gjøre det.

Det finnes TypeScript-kompileringsplugins tilgjengelig for Webpack, Gulp, Grunt og nesten alle andre JavaScript-byggverktøy der ute. TypeScript-dokumentasjonen har en seksjon om integrering med byggverktøy som dekker dem alle. En linter er også tilgjengelig hvis du ønsker enda mer sjekking under bygging. Det finnes også et stort antall startprosjekter der ute som vil få deg i gang med TypeScript i kombinasjon med en rekke andre teknologier som Angular 2, React, Ember, SystemJS, Webpack, Gulp, osv.

JavaScript-samarbeid

Siden TypeScript er så nært knyttet til JavaScript, har det gode interoperabilitetsevner, men noe ekstra arbeid kreves for å arbeide med JavaScript-biblioteker i TypeScript. TypeScript-definisjoner er nødvendig slik at TypeScript-kompilatoren forstår at funksjonskall som _.groupBy eller angular.copy eller $.fadeOut faktisk ikke er ulovlige uttrykk. Definisjonene for disse funksjonene plasseres i .d.ts-filer.

Den enkleste formen en definisjon kan ta, er å la en identifikator brukes på hvilken som helst måte. For eksempel, når du bruker Lodash, vil en enkeltlinje definisjonsfil declare var _ : any tillate deg å kalle hvilken som helst funksjon du vil på _, men da kan du selvfølgelig også fortsatt gjøre feil: _.foobar() ville være en lovlig TypeScript-kall, men er selvfølgelig en ulovlig kall under kjøring. Hvis du vil ha skikkelig typesupport og kodefullføring, må definisjonsfilen din være mer presis (se lodash-definisjoner for et eksempel).

Npm-moduler som leveres forhåndspakket med sine egne typedefinisjoner blir automatisk forstått av TypeScript-kompilatoren (se dokumentasjonen). For nesten alle andre halvpopulære JavaScript-bibliotek som ikke inkluderer sine egne definisjoner, har noen der ute allerede laget typedefinisjoner tilgjengelig gjennom en annen npm-modul. Disse modulene har prefikset "@types/" og kommer fra et Github-depot kalt DefinitelyTyped.

Det er ett forbehold: typedefinisjonene må samsvare med versjonen av biblioteket du bruker ved kjøring. Hvis de ikke gjør det, kan TypeScript hindre deg i å kalle en funksjon eller referere til en variabel som eksisterer, eller tillate deg å kalle en funksjon eller referere til en variabel som ikke eksisterer, simpelthen fordi typene ikke samsvarer med kjøringstiden under kompilering. Så sørg for at du laster riktig versjon av typedefinisjonene for riktig versjon av biblioteket du bruker.

For å være ærlig, er det en liten ulempe med dette, og det kan være en av grunnene til at du ikke velger TypeScript, men i stedet går for noe som Babel som ikke lider av å måtte skaffe type-definisjoner i det hele tatt. På den annen side, hvis du vet hva du gjør, kan du lett overvinne enhver slags problemer forårsaket av feil eller manglende definisjonsfiler.

Konvertering fra JavaScript til TypeScript

Enhver .js-fil kan gis nytt navn til en .ts-fil og kjøres gjennom TypeScript-kompilatoren for å få syntaktisk det samme JavaScript-koden som output (hvis den var syntaktisk korrekt i utgangspunktet). Selv når TypeScript-kompilatoren får kompilasjonsfeil, vil den fortsatt produsere en .js-fil. Den kan til og med akseptere .js-filer som input med --allowJs-flagget. Dette lar deg starte med TypeScript med en gang. Dessverre er det sannsynlig at kompilasjonsfeil vil oppstå i begynnelsen. Man må huske at disse ikke er stoppende feil som man kanskje er vant til med andre kompilatorer.

Kompileringsfeilene man får i begynnelsen når man konverterer et JavaScript-prosjekt til et TypeScript-prosjekt, er uunngåelige på grunn av TypeScripts natur. TypeScript sjekker all kode for gyldighet, og derfor må den vite om alle funksjoner og variabler som brukes. Dermed må typedefinisjoner være på plass for alle, ellers er det bundet til å oppstå kompilasjonsfeil. Som nevnt i kapitlet ovenfor, finnes det for praktisk talt hvert JavaScript-rammeverk .d.ts-filer som enkelt kan skaffes ved installasjon av DefinitelyTyped-pakker. Det kan imidlertid være at du har brukt et obskurt bibliotek som ikke har tilgjengelige TypeScript-definisjoner, eller at du har polyfilt noen JavaScript-primitiver. I så fall må du levere typedefinisjoner for disse delene for at kompileringsfeilene skal forsvinne. Bare opprett en .d.ts-fil og inkluder den i tsconfig.jsons files-array, slik at den alltid blir vurdert av TypeScript-kompilatoren. I filen deklarerer du de delene som TypeScript ikke kjenner til som type any. Når du har fjernet alle feil, kan du gradvis innføre typing på disse delene i henhold til ditt behov.

Noe arbeid med å (re)konfigurere byggeprosessen din vil også være nødvendig for å få TypeScript inn i byggeprosessen. Som nevnt i kapitlet om kompilering finnes det mange gode ressurser der ute, og jeg oppfordrer deg til å se etter startprosjekter som bruker kombinasjonen av verktøy du ønsker å jobbe med.

Den største hindringen er læringskurven. Jeg oppfordrer deg til å leke med et lite prosjekt først. Se hvordan det fungerer, hvordan det bygges, hvilke filer det bruker, hvordan det er konfigurert, hvordan det fungerer i IDE-en din, hvordan det er strukturert, hvilke verktøy det bruker, osv. Å konvertere en stor JavaScript-kodebase til TypeScript er gjennomførbart når du vet hva du gjør. Les for eksempel denne bloggen om å konvertere 600 000 linjer til TypeScript på 72 timer. Bare sørg for at du har en god forståelse av språket før du tar steget.

Adopsjon

TypeScript er åpen kildekode (Apache 2-lisensiert, se GitHub) og støttet av Microsoft. Anders Hejlsberg, hovedarkitekten av C#, leder prosjektet. Det er et veldig aktivt prosjekt; TypeScript-teamet har gitt ut mange nye funksjoner de siste årene, og mange flotte funksjoner er fortsatt planlagt å komme (se veikartet).

Noen fakta om adopsjon og popularitet:

  • I StackOverflow-undersøkelsen for utviklere i 2017 var TypeScript den mest populære JavaScript-transpileren (9. plass totalt) og vant tredjeplass i kategorien mest elskede programmeringsspråk.
  • I 2018 State of JS-undersøkelsen ble TypeScript erklært som en av de to store vinnerne i kategorien JavaScript-varianter (med ES6 som den andre).
  • I StackOverflow-utviklerundersøkelsen fra 2019 steg TypeScript til 9. plass over de mest populære språkene blant profesjonelle utviklere, og overgikk både C og C++. Det tok igjen tredjeplass blant de mest elskede språkene.
  • I StackOverflow-utviklerundersøkelsen i 2020 var TypeScript den nest mest elskede teknologien.

Svar #3

TypeScript gjør noe lignende det less eller sass gjør for CSS. De er supersett av det, noe som betyr at all JS-kode du skriver er gyldig TypeScript-kode. I tillegg kan du bruke de andre fordelene det tilfører språket, og den transpilerte koden vil være gyldig JS. Du kan til og med sette hvilken JS-versjon du vil at den resulterende koden skal være på.

For øyeblikket er TypeScript en supermengde av ES2015, så det kan være et godt valg å begynne å lære de nye JS-funksjonene og transpile til den nødvendige standarden for prosjektet ditt.

Svar #4

"TypeScript Fundamentals" -- et Pluralsight videokurs av Dan Wahlin og John Papa er en virkelig god, for øyeblikket (25. mars 2016) oppdatert for å gjenspeile TypeScript 1.8, introduksjon til TypeScript.

For meg er de virkelig gode funksjonene, bortsett fra de fine mulighetene for intellisense, klassene, grensesnittene, modulene, enkelheten ved implementering av AMD, og muligheten til å bruke Visual Studio Typescript-feilsøkeren når den kjøres med IE.

For å oppsummere: Hvis det brukes som tiltenkt, kan Typescript gjøre JavaScript-programmering mer pålitelig og enklere. Det kan øke produktiviteten til JavaScript-programmøren betydelig gjennom hele SDLC.

Svar #5

Ecma script 5 (ES5) som alle nettlesere støtter og er forhåndskompilert. ES6/ES2015 og ES2016 kom i år med mange endringer, så for å fremheve disse endringene finnes det noe imellom som bør ta vare på dette, nemlig TypeScript.

• TypeScript er typer -> Dette betyr at vi må definere datatype for hver egenskap og metode. Hvis du kjenner C#, er TypeScript lett å forstå.

• Stor fordel med TypeScript er at vi kan identifisere type-relaterte problemer tidlig før produksjon. Dette gjør at enhetstester kan feile hvis det er noen type-mismatch.

Relaterte artikler