A Practical Guide to TypeScript for Developers



I present to your attention the translation of the article "Working With TypeScript: A Practical Guide for Developers" .







What is TypeScript?



TypeScript — (static type checker) (typed superset) JavaScript, , Microsoft JavaScript.







TypeScript , Apache 2.0, , JavaScript.







TypeScript



, TypeScript, (command line interface, CLI), - .







Node.js. , , Node.js- TypeScript:







#     
mkdir typescript-intro

#    
cd typescript-intro

#  Node.js-
npm init -y

#   TypeScript
npm i typescript
      
      





tsc



( TypeScript) . , , index.ts



:







console.log(1)
      
      





, , JavaScript:







#  index.ts  index.js
npx tsc index.ts
      
      





, node



:







#    `1`  
node index.js
      
      





, , , .







: TypeScript , . TypeScript npx



, , .







TypeScript-



TypeScript- Node.js-, tsconfig.json



. , TypeScript-.







tsconfig.json



, , , , , , ..







TypeScript :







#   tsconfig.json
npx tsc --init
      
      





tsconfig.json



. , , .







TypeScript, .







TypeScript



TypeScript " TypeScript". . , , TypeScript.









TypeScript JavaScript . .







test.js



:







function addOne(age) {
 return age + 1
}

const age = 'thirty two'

console.log(addOne(age))
      
      





:







node test.js
      
      





  1. ?
  2. , ?


thirty two1



- . : JavaScript.







, addOne()



? typeof



TypeScript, .







index.ts



:







function addOne(age: number): number {
 return age + 1
}

console.log(addOne(32))
console.log(addOne('thirty two'))
      
      





, number



.







:







npx tsc index.ts
      
      





:







index.ts:6:20 - error TS2345: Argument of type 'string' is not
assignable to parameter of type 'number'.   ''        ''.
      
      





, , .







string



number



, TypeScript. TypeScript JavaScript, boolean



symbol



.







, TypeScript , JavaScript, :







  • enum



  • any



    — , / , , ,
  • unknown



    any



  • void



    — ,
  • never



    — , ,
  • , number



    , string



    boolean



    . , , 'Hello World' — string



    , string



    — 'Hello World' . false



    3



    :


//      ,   3  4
declare function processNumber(s: 3 | 4)
declare function processAnyNumber(n: number)

const n: number = 10
const n2: 3 = 3

processNumber(n) // : `number` -   `3 | 4`
processAnyNumber(n2) // . 3 -  `number`
      
      







TypeScript ( , — , ), .







(maps)



, , :







//   
type User = {
 id: number
 username: string
 name: string
}

//   `user`,   
const user: User = {
 id: 1,
 username: 'Superman',
 name: 'Clark Kent',
}
      
      





(vectors)



— , . JavaScript , TypeScript :







//   
type User = {
 id: number
 username: string
 name: string
}

//    `user`,   
const user1: User = {
 id: 1,
 username: 'Superman',
 name: 'Clark Kent',
}

const user2: User = {
 id: 2,
 username: 'WonderWoman',
 name: 'Diana Prince',
}

const user3: User = {
 id: 3,
 username: 'Spiderman',
 name: 'Peter Parker',
}

//   
const userVector: User[] = [user1, user2, user3]
      
      





(tuples)



, :







//   
type User = {
 id: number
 username: string
 name: string
}

//   `user`,   
const user1: User = {
 id: 1,
 username: 'Superman',
 name: 'Clark Kent',
}

//  
const userTuple: [User, number] = [user1, 10]
      
      





(unions)



, , .







, , .







, node-fetch



, fetch



Node.js:







npm i node-fetch @types/node-fetch
      
      





typeof



:







type User = {
 id: number
 username: string
 name: string
 email: string
}

async function fetchFromEmail(email: string) {
 const res = await fetch('https://jsonplaceholder.typicode.com/users')
 const parsed: User[] = await res.json()
 const user = parsed.find((u: User) => u.email === email)

 if (user) {
   return fetchFromId(user.id)
 }
 return undefined
}

function fetchFromId(id: number) {
 return fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
   .then((res) => res.json())
   .then((user) => user.address)
}

function getUserAddress(user: User | string) {
 if (typeof user === 'string') {
   return fetchFromEmail(user)
 }
 return fetchFromId(user.id)
}

getUserAddress('Rey.Padberg@karina.biz').then(console.log).catch(console.error)
      
      





.







, :







const userTuple: Array<User | number> = [u, 10, 20, u, 30]
//      `User`,  `number`
      
      





:







const userTuple: [User, number] = [u, 10, 20, u, 30]
// :         `User`  `number`
const anotherUserTuple: [User, number] = [u, 10] //  
      
      





(type guards)



— , , (narrow) (scope) .







typeof



, user



.







, instanceof



, !==



in



, .







, , ( , ):







//    `user`
function isUser(u: unknown): u is User {
 if (u && typeof u === 'object') {
   return 'username' in u && 'currentToken' in u
 }
 return false
}

function getUserAddress(user: User | string) {
 if (isUser(user)) {
   return fetchFromEmail(user)
 }
 return fetchFromId(user.id)
}
      
      





, TypeScript .







JSON-, , Ajv. , -, unknown



( any



), :







import Ajv from 'ajv'
const ajv = new Ajv()

const validate = ajv.compile({
 type: 'object',
 properties: {
   username: { type: 'string' },
   currentToken: { type: 'string' },
 },
})

function validateUser(data: unknown): data is User {
 return validate(data)
}
      
      





JSON- . , , .







, .







(discriminated unions)



. TypeScript , :







type Member = {
 type: 'member'
 currentProject: string
}

type Admin = {
 type: 'admin'
 projects: string[]
}

type User = Member | Admin

function getFirstProject(u: User) {
 if (u.type === 'member') {
   return u.currentProject
 }
 return u.projects[0]
}
      
      





getFirstProject()



TypeScript . projects



( if



) .









, , .







, . :







function validateUser(data: unknown): data is User {
 return true
}
      
      





true



, , :







const invalidUser = undefined

if (validateUser(invalidUser)) {
 //     `true`
 console.log(invalidUser.name) // ,    
}
      
      





, . runtypes, io-ts fp-ts.







, ( ) , io-ts



; (decoder); , - :







import * as D from 'io-ts/Decoder';
import * as E from 'io-ts/Either';
import { pipe } from 'fp-ts/function';

//  ,  `user`
const UserDecoder = D.type({
   id: D.number,
   username: D.string,
   name: D.string
   email: D.string
});

//        
pipe(
   UserDecoder.decode(data),
   E.fold(
       error => console.log(D.draw(error)),
       decodedData => {
           //  `decodedData`  `User`
           console.log(decodedData.username)
       }
   )
);
      
      





TypeScript



tsconfig.json



, .







, 3 :







  1. : / , TypeScript-, (aliases).
  2. : null



    undefined



    , const enums



    ..
  3. .


TSConfig



TypeScript ES3



(CommonJS, SystemJS .).







. , Node.js 10, ES2015



CommonJS



.







Node.js, , 14 15, ESNext



ES2020



ESNext



.







, , webpack



parcel



, UMD



.







, TypeScript , tsconfig.json



:







{
 "extends": "@tsconfig/node12/tsconfig.json",
 "include": ["src"]
}
      
      





, :







  • declaration



    : , TypeScript (.d.ts



    ) . , ,
  • noEmitOnError



    : , TypeScript , . true



  • removeComments



    : true



  • suppressImplicitAnyIndexErrors



    : true



  • strict



    : . , , true



  • noEmitHelpers



    : , TypeScript , ES3



    ES5



    . false



    , , , (tslib



    )




, , TypeScript, , TypeScript JavaScript -.







TypeScript , , .










JavaScript.







10% !














All Articles