Strongly typed Javascript.
-
- JavaScript superset
- Build upon JS and adds new features to it
- can't be executed directly by the JS environment (browser, node)
- is compiled to pure JS
- TS features are compiled to JS "workarounds"
- add types and type checking to the JS
-
What will happen?
function add(num1, num2) {
return num1 + num2;
}
console.log(add("1", 2));
-
- the console will log
12
- will not throw runtime error
- but might be a logical error
- possible mitigation: validate & sanitize user input
- wouldn't it be better to discover this during development?
-
- types and type-checking
- type-errors are discovered during compilation rather than runtime
- great IDE support that prompts errors even before compilation
- next-gen JS features compiled for older versions
-
- adds non-JS features like Interfaces and Generics
- adds meta-programming features like Decorators
- early adoption of new ECMAScript features
- rich configuration options
- great support in 3rd party libs (either they are written in TS types for it are available)
-
- more typing (in both meanings of the word)
- adds compilation step to the workflow
- can make building the project more complex
-
- requires node.js to be installed
- install TS compiler with the following command
npm install -g typescript
-
- to compile single file once
tsc ${file.name}
- to compile single file each time it changes
# short
tsc -w ${file.name}
# long
tsc --watch ${file.name}
-
Type | Descritption | Example |
---|---|---|
number |
all numbers, no disctintion between integers and floats | 10 , 5.3 |
string |
all text values | 'Hi, "Hi", `Hi` |
boolean |
just true/false, no "truthy/falsy" JS nonsense | true/false |
-
Type | Descritption | Example |
---|---|---|
object |
Any JS object, more specific types can be defined | {age: 30} |
Array |
Any JS array, element types can be strict or flexible | [1,2,3] |
-
Type | Descritption | Example |
---|---|---|
Tuple |
Fixed lenght and type array | [1,2] |
Enum |
Enumerated list of values | enum{NEW,OLD} |
Any |
Any type possible, disables type checking | * |
-
Type | Description |
---|---|
Function |
Pointer to function |
unknown |
When the incoming type is not known |
never |
For functions that don't return (interrupted by error or infinite loop) |
-
- to assign type use the
: ${type}
syntax
// Variables
const number1: number = 1;
// Function parameters
const f1 = (par1: number, par2: string) => {};
// Function return value
const f2 = (n1, n2): nubmer => {};
-
- TS can infer the type from the context
- it's considered bad practice to specify a type that can be inferred
let num1 = 1; //number
let someString = "abc"; //string
-
- it is possible to specify object type with keys and type of their value:
const person: {
name: string;
age: number;
} = {
name: "Malanius",
age: 30,
};
-
- fixed type arrays can be defined as
${type}[]
- a flexible array can be defined as
any[]
, but you lose type checking
const arr: string[];
-
-
tuple in TS is fixed length, fixed type array
-
TS check assignment to tuple array to have the correct type
-
it is still possible to push to tuple array
-
can be defined as:
const t: [nubmer, string] = [1, "string"];
-
- works similar as you know from other languages
- definition:
enum {
NEW, //0
OLD //1
}
-
- it is possible to define custom ordinals
enum {
NEW = 5, //5
OLD //6
}
-
- it is also possible to use a different type than numbers for ordinals
enum {
NEW = 'NEW', //NEW
OLD
}
- be careful with this, always have a good reason to do it
-
- disables type checking
- behaves as plain JS does
- avoid whenever possible (why use TS when you have everything
any
?) - possible to configure compilation to mark use of
any
as error
-
- sometimes, you need to support multiple types in variable, this can be done with union types
- defined as
${type} | ${type}...
- example:
const combine = (input1: number | string, input2: number | string) => {};
-
- it is possible to add specific value instead of type
- can be combined with union types to allow several values
const combine = (
resultConversion: "as-number" | "as-text";
) => {}
-
- it can be cumbersome to always repeat union types or other complex types
- type aliases allow defining custom types that can be used later
- possible to define an alias for type with
type
keyword
type Combinable = number | string;
type Person = {
name: string,
age: number;
}
const value: Combinable = 1;
const someone: Person = {...}
-
- each function has a return type, mostly it's inferred by TS
- possible to define return type manually with specifying return types after parameters:
- a function that doesn't return value has a
void
return type (in pure JSundefined
is returned withreturn
statement) undefined
is a valid type in TS, will requirereturn
in the function
const add = (n1: number, n2: number): number => {
return n1 + n2;
};
-
- used to specify that some variable should hold a function pointer
- function types can be declared as well
let combineValues: (a: number, b: number) => number;
- it is also possible to define type of
callback
function:
const addAndHandle = (n1: number, n2: number, cb: (num: number) => void) => {
const result = n1 + n2;
cb(result);
};
-
- useful in cases we don't exactly know what will be stored in the variable
- more restrictive than
any
- prevents assigning unknown variables to typed ones without type-check
- way better choice than
any
when input is not known before
-
let userInput: unknown;
let userName: string;
userInput = 5;
userInput = "String";
// userName = userInput; // won't work as unknown can't be assigned to string
//TS detects this check and allows assignment of the unknown type to string
if (typeof userInput === "string") {
userName === userInput;
}
-
- specifies that function doesn't return anything, even default undefined
- useful when function always throws an error or has an infinite loop
const generateError = (message: string, code: number): never => {
throw { message: message, errorCode: code };
};
-
- initialize TS project with
tsc --init
- this creates
tsconfig.json
file containing TS compilator configuration - now you can use
tsc
ortsc --watch
to compile whole project
-
- in
tsconfig.json
you can specify files to be included or exluded in the compilation exlude
- paths in this list won't be compiledinclude
- only paths specified here will be compiled, can be filtered with excludeexclude
orinclude
parameters in the configuration files takes a list of- files to be included/excluded
- folder to be included/exluded
- supports wildcard globbing
-
files
- you can specify concere files to compile, no paths or globbing here
-
target
- which version of JS the TS code should be compiled intomodule
- specifies how modules are generated (will be dealt with in own section)lib
- specify which default objects and features TS knows
- defaults to target
es
and allDOM
APIs for web browser
-
allowJS
- allows JS files to be compiled by TScheckJS
- checks JS files for errors, but won't compilejsx
- specifies how to compile JSX for React
-
when building a lib to be used by others, you can include type definitions with it:
declaration
- creates.d.ts
filesdeclarationMap
- generates source maps for.d.ts
files
-
sourceMap
- generates source map for debugging purposes
-
outFile
- concatenate and emit output to single file
- tricky to use properly, see here
rootDir
- where the root of the source files is, typicallysrc
outDir
- where the compiled output should go, i.e.dist
-
noEmit
- will not produce JS files, but still checks the TS filesnoEmitOnError
- will not produce compiled JS files when errors are present
-
strict
- sets all strict options on/offnoImplicitAny
- raise error when implicitany
is present (the type is not specified)strictNullChecks
- requires checks for null for potentially nullable values
-
strictFunctionTypes
- cheks for function types while inheritingstrictBindCallApply
- strict check bind, call, apply functions assigmentsstrictPropertyInitialization
- Ensure non-undefined class properties are initialized in the constructor
-
noImplicitThis
-this
impliead asany
will cause erroralwaysStrict
- generated JS files will always have "strict mode" ("use strict"
)
-
noUnusedLocals
- reports unused local variablesnoUnusedParameters
- reports unused function parametersnoImplicitReturns
- check if all code paths in function returns a valuenoFallthroughCasesInSwitch
- checks missingbreak
statements inswitch
-
-
const
- constant value, can't be changedlet
- variable value, changeable- difference between them and old
var
is in how the're scoped -var
has only function or global scope, no local/block scope for it exists - compiled to
var
on target < ES6
-
- for the shorhand of one param fucntions, it is required to have type of the function and its params specified
- compiled to function varibales on target < ES6
-
- default arguments has to be last on the list of arguments
- compiled to workaroud that cheks for assigned value on target < ES6
-
- useful for pulling values from arrays or copying objects
- compiled to workarounds on target < ES6
-
- useful for crating functions with variable number of parameters
- provided parameters are covnerted to array
- can be combined with tuples if number of arguments is known before
- compiled to workaround that collects the parameters to the array on target < ES6
-
- useful shorthand for pullign specific values from arrays or objects to varibales
- doesn't change original value/object
- compiled to workarounds using old approach on target < ES6