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-.
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
- ?
- , ?
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
.
, , ( , ):
// `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) // , }
, ( ) , 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 :
- : / , TypeScript-, (aliases).
- :
null
undefined
,const enums
.. - .
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 , , .
10% !