Was this page helpful?

TypeScript for JavaScript Programmers

TypeScript stands in an unusual relationship to JavaScript. TypeScript offers all of JavaScript’s features, and an additional layer on top of these: TypeScript’s type system.

For example, JavaScript provides language primitives likestring andnumber, but it doesn’t check that you’ve consistently assigned these. TypeScript does.

This means that your existing working JavaScript code is also TypeScript code. The main benefit of TypeScript is that it can highlight unexpected behavior in your code, lowering the chance of bugs.

This tutorial provides a brief overview of TypeScript, focusing on its type system.

Types by Inference

TypeScript knows the JavaScript language and will generate types for you in many cases.For example in creating a variable and assigning it to a particular value, TypeScript will use the value as its type.

ts
lethelloWorld ="Hello World";
let helloWorld: string
Try

By understanding how JavaScript works, TypeScript can build a type-system that accepts JavaScript code but has types. This offers a type-system without needing to add extra characters to make types explicit in your code. That’s how TypeScript knows thathelloWorld is astring in the above example.

You may have written JavaScript in Visual Studio Code, and had editor auto-completion. Visual Studio Code uses TypeScript under the hood to make it easier to work with JavaScript.

Defining Types

You can use a wide variety of design patterns in JavaScript. However, some design patterns make it difficult for types to be inferred automatically (for example, patterns that use dynamic programming). To cover these cases, TypeScript supports an extension of the JavaScript language, which offers places for you to tell TypeScript what the types should be.

For example, to create an object with an inferred type which includesname: string andid: number, you can write:

ts
constuser = {
name:"Hayes",
id:0,
};
Try

You can explicitly describe this object’s shape using aninterface declaration:

ts
interfaceUser {
name:string;
id:number;
}
Try

You can then declare that a JavaScript object conforms to the shape of your newinterface by using syntax like: TypeName after a variable declaration:

ts
constuser:User = {
name:"Hayes",
id:0,
};
Try

If you provide an object that doesn’t match the interface you have provided, TypeScript will warn you:

ts
interfaceUser {
name:string;
id:number;
}
 
constuser:User = {
username:"Hayes",
Object literal may only specify known properties, and 'username' does not exist in type 'User'.2353Object literal may only specify known properties, and 'username' does not exist in type 'User'.
id:0,
};
Try

Since JavaScript supports classes and object-oriented programming, so does TypeScript. You can use an interface declaration with classes:

ts
interfaceUser {
name:string;
id:number;
}
 
classUserAccount {
name:string;
id:number;
 
constructor(name:string,id:number) {
this.name =name;
this.id =id;
}
}
 
constuser:User =newUserAccount("Murphy",1);
Try

You can use interfaces to annotate parameters and return values to functions:

ts
functiondeleteUser(user:User) {
// ...
}
 
functiongetAdminUser():User {
//...
}
Try

There is already a small set of primitive types available in #"/play#example/unknown-and-never">unknown (ensure someone using this type declares what the type is),never (it’s not possible that this type could happen), andvoid (a function which returnsundefined or has no return value).

You’ll see that there are two syntaxes for building types:Interfaces and Types. You should preferinterface. Usetype when you need specific features.

Composing Types

With TypeScript, you can create complex types by combining simple ones. There are two popular ways to do so: unions and generics.

Unions

With a union, you can declare that a type could be one of many types. For example, you can describe aboolean type as being eithertrue orfalse:

ts
typeMyBool =true |false;
Try

Note: If you hover overMyBool above, you’ll see that it is classed asboolean. That’s a property of the Structural Type System. More on this below.

A popular use-case for union types is to describe the set ofstring ornumberliterals that a value is allowed to be:

ts
typeWindowStates ="open" |"closed" |"minimized";
typeLockStates ="locked" |"unlocked";
typePositiveOddNumbersUnderTen =1 |3 |5 |7 |9;
Try

Unions provide a way to handle different types too. For example, you may have a function that takes anarray or astring:

ts
functiongetLength(obj:string |string[]) {
returnobj.length;
}
Try

To learn the type of a variable, usetypeof:

TypePredicate
stringtypeof s === "string"
numbertypeof n === "number"
booleantypeof b === "boolean"
undefinedtypeof undefined === "undefined"
functiontypeof f === "function"
arrayArray.isArray(a)

For example, you can make a function return different values depending on whether it is passed a string or an array:

ts
functionwrapInArray(obj:string |string[]) {
if (typeofobj ==="string") {
return [obj];
(parameter) obj: string
}
returnobj;
}
Try

Generics

Generics provide variables to types. A common example is an array. An array without generics could contain anything. An array with generics can describe the values that the array contains.

ts
typeStringArray =Array<string>;
typeNumberArray =Array<number>;
typeObjectWithNameArray =Array<{name:string }>;

You can declare your own types that use generics:

ts
interfaceBackpack<Type> {
add: (obj:Type)=>void;
get: ()=>Type;
}
 
// This line is a shortcut to tell TypeScript there is a
// constant called `backpack`, and to not worry about where it came from.
declareconstbackpack:Backpack<string>;
 
// object is a string, because we declared it above as the variable part of Backpack.
constobject =backpack.get();
 
// Since the backpack variable is a string, you can't pass a number to the add function.
backpack.add(23);
Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.
Try

Structural Type System

One of TypeScript’s core principles is that type checking focuses on theshape that values have. This is sometimes called “duck typing” or “structural typing”.

In a structural type system, if two objects have the same shape, they are considered to be of the same type.

ts
interfacePoint {
x:number;
y:number;
}
 
functionlogPoint(p:Point) {
console.log(`${p.x},${p.y}`);
}
 
// logs "12, 26"
constpoint = {x:12,y:26 };
logPoint(point);
Try

Thepoint variable is never declared to be aPoint type. However, TypeScript compares the shape ofpoint to the shape ofPoint in the type-check. They have the same shape, so the code passes.

The shape-matching only requires a subset of the object’s fields to match.

ts
constpoint3 = {x:12,y:26,z:89 };
logPoint(point3);// logs "12, 26"
 
constrect = {x:33,y:3,width:30,height:80 };
logPoint(rect);// logs "33, 3"
 
constcolor = {hex:"#187ABF" };
logPoint(color);
Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'. Type '{ hex: string; }' is missing the following properties from type 'Point': x, y2345Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'. Type '{ hex: string; }' is missing the following properties from type 'Point': x, y
Try

There is no difference between how classes and objects conform to shapes:

ts
classVirtualPoint {
x:number;
y:number;
 
constructor(x:number,y:number) {
this.x =x;
this.y =y;
}
}
 
constnewVPoint =newVirtualPoint(13,56);
logPoint(newVPoint);// logs "13, 56"
Try

If the object or class has all the required properties, TypeScript will say they match, regardless of the implementation details.

Next Steps

This was a brief overview of the syntax and tools used in everyday TypeScript. From here, you can:

The TypeScript docs are an open source project. Help us improve these pagesby sending a Pull Request

Contributors to this page:
OTOrta Therox  (24)
JBJonathan Berger  (1)
DSDustin Stender  (1)
MKMatt Kantor  (1)
JCRJuan Carlos Ruiz  (1)
19+

Last updated: Jul 14, 2025