HSLA color values are an extension of HSL with an Alpha channel
(opacity).
HSL Color Values
In HTML, a color can be specified using hue, saturation, and lightness (HSL) in
the form:
hsl(hue, saturation, lightness)
Hue is a degree on the color wheel from 0 to 360. 0 is red, 120 is green, and 240 is blue.
Saturation is a percentage value. 0% means a shade of gray, and 100% is the full color.
Lightness is also a percentage value. 0% is black, and 100% is white.
Experiment by mixing the HSL values below:
HUE
0
SATURATION
100%
LIGHTNESS
50%
Example
hsl(0, 100%, 50%)
hsl(240, 100%, 50%)
hsl(147, 50%, 47%)
hsl(300, 76%, 72%)
hsl(39, 100%, 50%)
hsl(248, 53%, 58%)
Saturation
Saturation can be described as the intensity of a color.
100% is pure color, no shades of gray.
50% is 50% gray, but you can still see the color.
0% is completely gray; you can no longer see the color.
Example
hsl(0, 100%, 50%)
hsl(0, 80%, 50%)
hsl(0, 60%, 50%)
hsl(0, 40%, 50%)
hsl(0, 20%, 50%)
hsl(0, 0%, 50%)
Lightness
The lightness of a color can be described as how much light you want to give the color, where 0% means no light (black), 50% means 50% light (neither dark nor light),
and 100% means full lightness (white).
Example
hsl(0, 100%, 0%)
hsl(0, 100%, 25%)
hsl(0, 100%, 50%)
hsl(0, 100%, 75%)
hsl(0, 100%, 90%)
hsl(0, 100%, 100%)
Shades of Gray
Shades of gray are often defined by setting the hue and saturation to 0, and
adjusting the lightness from 0% to 100% to get darker/lighter shades:
Example
hsl(0, 0%, 20%)
hsl(0, 0%, 30%)
hsl(0, 0%, 40%)
hsl(0, 0%, 60%)
hsl(0, 0%, 70%)
hsl(0, 0%, 90%)
HSLA Color Values
HSLA color values are an extension of HSL color values, with an Alpha channel
- which specifies the opacity for a color.
An HSLA color value is
specified with:
hsla(hue,saturation, lightness,
alpha)
The alpha parameter is a number
between 0.0 (fully transparent) and 1.0 (not transparent at all):
Experiment by mixing the HSLA values below:
HUE
0
SATURATION
100%
LIGHTNESS
50%
ALPHA
0.5
Example
hsla(9, 100%, 64%, 0)
hsla(9, 100%, 64%, 0.2)
hsla(9, 100%, 64%, 0.4)
hsla(9, 100%, 64%, 0.6)
hsla(9, 100%, 64%, 0.8)
hsla(9, 100%, 64%, 1)
TypeScript Tutorial
TypeScript is JavaScript with added syntax for types.
Examples in Each Chapter
Our "Try it Yourself" editor makes it easy to learn TypeScript.
You can edit TypeScript code and view the result in your browser.
Example
console.log('Hello World!');
Click on the "Try it Yourself" button to see how it works.
We recommend reading this tutorial in the sequence listed in the left menu.
TypeScript Exercises
My Learning
Track your progress with the free "My Learning" program here at W3Schools.
Log in to your account, and start earning points!
This is an optional feature. You can study W3Schools without using My Learning.
TypeScript is JavaScript with added syntax for types.
What is TypeScript?
TypeScript is a syntactic superset of JavaScript which adds static typing.
This basically means that TypeScript adds syntax on top of JavaScript, allowing developers to add types.
TypeScript being a "Syntactic Superset" means that it shares the same base syntax as JavaScript, but adds something to it.
Why should I use TypeScript?
JavaScript is a loosely typed language. It can be difficult to understand what types of data are being passed around in JavaScript.
In JavaScript, function parameters and variables don't have any information! So developers need to look at documentation, or guess based on the implementation.
TypeScript allows specifying the types of data being passed around within the code, and has the ability to report errors when the types don't match.
For example, TypeScript will report an error when passing a string into a function that expects a number. JavaScript will not.
TypeScript uses compile time type checking. Which means it checks if the specified types match before running the code, not while running the code.
How do I use TypeScript?
A common way to use TypeScript is to use the official TypeScript compiler, which transpiles TypeScript code into JavaScript.
The next section shows how to get the compiler setup for a local project.
Some popular code editors, such as Visual Studio Code, have built-in TypeScript support and can show errors as you write code!
TypeScript Exercises
TypeScript Compiler
TypeScript is transpiled into JavaScript using a compiler.
TypeScript being converted into JavaScript means it runs anywhere that JavaScript runs!
Installing the Compiler
TypeScript has an official compiler which can be installed through npm.
Learn more about npm, and how to get started here:
Within your npm project, run the following command to install the compiler:
npm install typescript --save-dev
Which should give you an output similar to:
added 1 package, and audited 2 packages in 2s found 0 vulnerabilities
The compiler is installed in the node_modules directory and can be run with: npx tsc.
npx tsc
Which should give you an output similar to:
Version 4.5.5 tsc: The TypeScript Compiler - Version 4.5.5
Followed by a list of all the Commmon Commands.
Configuring the compiler
By default the TypeScript compiler will print a help message when run in an empty project.
The compiler can be configured using a tsconfig.json file.
You can have TypeScript create tsconfig.json with the recommended settings with:
npx tsc --init
Which should give you an output similar to:
Created a new tsconfig.json with: TS target: es2016 module: commonjs strict: true esModuleInterop: true skipLibCheck: true forceConsistentCasingInFileNames: true
You can learn more at https://aka.ms/tsconfig.json
Here is an example of more things you could add to the tsconfig.json file:
You can open the file in an editor to add those options. This will configure the TypeScript compiler to transpile TypeScript files located in the src/ directory of your project, into JavaScript files in the build/ directory.
This is one way to quickly get started with TypeScript, there are many other options available such as a , a , and a .
TypeScript Exercises
TypeScript supports some simple types (primitives) you may know.
There are three main primitives in JavaScript and TypeScript.
boolean - true or false values
number - whole numbers and floating point values
string - text values like "TypeScript Rocks"
There are also 2 less common primitives used in later versions of Javascript and TypeScript.
bigint - whole numbers and floating point values, but allows larger negative and positive numbers than the number type.
symbol are used to create a globally unique identifier.
Type Assignment
When creating a variable, there are two main ways TypeScript assigns a type:
Explicit
Implicit
In both examples below firstName is of type string
Explicit Type
Explicit - writing out the type:
let firstName: string = "Dylan";
Explicit type assignment are easier to read and more intentional.
Implicit Type
Implicit - TypeScript will "guess" the type, based on the assigned value:
let firstName = "Dylan";
Note: Having TypeScript "guess" the type of a value is called infer.
Implicit assignment forces TypeScript to infer the value.
Implicit type assignment are shorter, faster to type, and often used when developing and testing.
Error In Type Assignment
TypeScript will throw an error if data types do not match.
Example
let firstName: string = "Dylan"; // type string firstName = 33; // attempts to re-assign the value to a different type
Implicit type assignment would have made firstName less noticeable as a string, but both will throw an error:
Example
let firstName = "Dylan"; // inferred to type string firstName = 33; // attempts to re-assign the value to a different type
JavaScript will not throw an error for mismatched types.
Unable to Infer
TypeScript may not always properly infer what the type of a variable may be. In such cases, it will set the type to any which disables type checking.
Example
// Implicit any as JSON.parse doesn't know what type of data it returns so it can be "any" thing... const json = JSON.parse("55"); // Most expect json to be an object, but it can be a string or a number like this example console.log(typeof json);
This behavior can be disabled by enabling noImplicitAny as an option in a TypeScript's project tsconfig.json. That is a JSON config file for customizing how some of TypeScript behaves.
Note: you may see primitive types capitalized like Boolean.
boolean !== Boolean For this tutorial just know to use the lower-cased values, the upper-case ones are for very specific circumstances.
TypeScript Exercises
TypeScript has special types that may not refer to any specific type of data.
Type: any
any is a type that disables type checking and effectively allows all types to be used.
The example below does not use any and will throw an error:
Example without any
let u = true; u = "string"; // Error: Type 'string' is not assignable to type 'boolean'. Math.round(u); // Error: Argument of type 'boolean' is not assignable to parameter of type 'number'.
Setting any to the special type any disables type checking:
Example with any
let v: any = true; v = "string"; // no error as it can be "any" type Math.round(v); // no error as it can be "any" type
any can be a useful way to get past errors since it disables type checking, but TypeScript will not be able provide type safety, and tools which rely on type data, such as auto completion, will not work. Remember, it should be avoided at "any" cost...
Type: unknown
unknown is a similar, but safer alternative to any.
TypeScript will prevent unknown types from being used, as shown in the below example:
let w: unknown = 1; w = "string"; // no error w = { runANonExistentMethod: () => { console.log("I think therefore I am"); } } as { runANonExistentMethod: () => void} // How can we avoid the error for the code commented out below when we don't know the type? // w.runANonExistentMethod(); // Error: Object is of type 'unknown'. if(typeof w === 'object' && w !== null) { (w as { runANonExistentMethod: Function }).runANonExistentMethod(); } // Although we have to cast multiple times we can do a check in the if to secure our type and have a safer casting
Compare the example above to the previous example, with any.
unknown is best used when you don't know the type of data being typed. To add a type later, you'll need to cast it.
Casting is when we use the "as" keyword to say property or variable is of the casted type.
Type: never
never effectively throws an error whenever it is defined.
let x: never = true; // Error: Type 'boolean' is not assignable to type 'never'.
never is rarely used, especially by itself, its primary use is in advanced generics.
Type: undefined & null
undefined and null are types that refer to the JavaScript primitives undefined and null respectively.
let y: undefined = undefined; let z: null = null;
These types don't have much use unless strictNullChecks is enabled in the tsconfig.json file.
TypeScript Exercises
TypeScript has a specific syntax for typing arrays.
Read more about arrays in our .
Example
const names: string[] = [];
names.push("Dylan"); // no error
// names.push(3); // Error: Argument of type 'number' is not assignable to parameter of type 'string'.
Readonly
The readonly keyword can prevent arrays from being changed.
Example
const names: readonly string[] = ["Dylan"];
names.push("Jack"); // Error: Property 'push' does not exist on type 'readonly string[]'.
// try removing the readonly modifier and see if it works?
Type Inference
TypeScript can infer the type of an array if it has values.
Example
const numbers = [1, 2, 3]; // inferred to type number[]
numbers.push(4); // no error
// comment line below out to see the successful assignment
numbers.push("2"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.
let head: number = numbers[0]; // no error
TypeScript Exercises
Typed Arrays
A tuple is a typed with a pre-defined length and types for each index.
Tuples are great because they allow each element in the array to be a known type of value.
To define a tuple, specify the type of each element in the array:
Example
// define our tuple
let ourTuple: [number, boolean, string];
// initialize correctly
ourTuple = [5, false, 'Coding God was here'];
As you can see we have a number, boolean and a string. But what happens if we try to set them in the wrong order:
Example
// define our tuple
let ourTuple: [number, boolean, string];
// initialized incorrectly which throws an error
ourTuple = [false, 'Coding God was mistaken', 5];
Even though we have a
boolean,
string,
and number the order matters in our tuple and will throw an error.
Readonly Tuple
A good practice is to make your tuplereadonly.
Tuples only have strongly defined types for the initial values:
Example
// define our tuple
let ourTuple: [number, boolean, string];
// initialize correctly
ourTuple = [5, false, 'Coding God was here'];
// We have no type safety in our tuple for indexes 3+
ourTuple.push('Something new and wrong');
console.log(ourTuple);
You see the new valueTuples only have strongly defined types for the initial values:
Example
// define our readonly tuple
const ourReadonlyTuple: readonly [number, boolean, string] = [5, true, 'The Real Coding God'];
// throws error as it is readonly.
ourReadonlyTuple.push('Coding God took a day off');
To learn more about access modifiers like readonly go to our section on them here: .
If you have ever used React before you have worked with tuples more than likely.
useState returns a tuple of the value and a setter function.
const [firstName, setFirstName] = useState('Dylan') is a common example.
Because of the structure we know our first value in our list will be a certain value type in this case a string and the second value a function.
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Named Tuples
Named tuples allow us to provide context for our values at each index.
Object types like this can also be written separately, and even be reused, look at for more details.
Type Inference
TypeScript can infer the types of properties based on their values.
Example
const car = {
type: "Toyota",
};
car.type = "Ford"; // no error
car.type = 2; // Error: Type 'number' is not assignable to type 'string'.
Optional Properties
Optional properties are properties that don't have to be defined in the object definition.
Example without an optional property
const car: { type: string, mileage: number } = { // Error: Property 'mileage' is missing in type '{ type: string;
}' but required in type '{ type: string; mileage: number; }'.
type: "Toyota",
};
car.mileage = 2000;
Example with an optional property
const car: { type: string, mileage?: number } = { // no error
type: "Toyota"
};
car.mileage = 2000;
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Index Signatures
Index signatures can be used for objects without a defined list of properties.
Example
const nameAgeMap: { [index: string]: number } = {};
nameAgeMap.Jack = 25; // no error
nameAgeMap.Mark = "Fifty"; // Error: Type 'string' is not assignable to type 'number'.
Index signatures like this one can also be expressed with utility types like Record<string, number>.
Learn more about utility types like this in our chapter.
TypeScript Exercises
An enum is a special "class" that represents a group of constants (unchangeable variables).
Enums come in two flavors string and numeric. Lets start with numeric.
Numeric Enums - Default
By default, enums will initialize the first value to 0 and add 1 to each additional value:
Example
enum CardinalDirections {
North,
East,
South,
West
}
let currentDirection = CardinalDirections.North;
// logs 0
console.log(currentDirection);
// throws error as 'North' is not a valid enum
currentDirection = 'North'; // Error: "North" is not assignable to type 'CardinalDirections'.
Numeric Enums - Initialized
You can set the value of the first numeric enum and have it auto increment from that:
Example
enum CardinalDirections {
North = 1,
East,
South,
West
}
// logs 1
console.log(CardinalDirections.North);
// logs 4
console.log(CardinalDirections.West);
Numeric Enums - Fully Initialized
You can assign unique number values for each enum value. Then the values will not incremented automatically:
Union types are used when a value can be more than a single type.
Such as when a property would be string or number.
Union | (OR)
Using the | we are saying our parameter is a string or number:
Example
function printStatusCode(code: string | number) {
console.log(`My status code is ${code}.`)
}
printStatusCode(404);
printStatusCode('404');
Union Type Errors
Note: you need to know what your type is when union types are being used to avoid type errors:
Example
function printStatusCode(code: string | number) {
console.log(`My status code is ${code.toUpperCase()}.`) // error: Property 'toUpperCase' does not exist ontype 'string | number'.
Property 'toUpperCase' does not exist on type 'number'
}
In our example we are having an issue invoking toUpperCase() as its a
string method and number doesn't have access
to it.
TypeScript Exercises
TypeScript has a specific syntax for typing function parameters and return values.
Read more about functions .
Return Type
The type of the value returned by the function can be explicitly defined.
Example
// the `: number` here specifies that this function returns a number
function getTime(): number {
return new Date().getTime();
}
If no return type is defined, TypeScript will attempt to infer it through the types of the variables or expressions returned.
Void Return Type
The type void can be used to indicate a function doesn't return any value.
Example
function printHello(): void {
console.log('Hello!');
}
Parameters
Function parameters are typed with a similar syntax as variable declarations.
Example
function multiply(a: number, b: number) {
return a * b;
}
If no parameter type is defined, TypeScript will default to using any, unless additional type information is available as shown in the Default Parameters and Type Alias sections below.
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Optional Parameters
By default TypeScript will assume all parameters are required, but they can be explicitly marked as optional.
Example
// the `?` operator here marks parameter `c` as optional
function add(a: number, b: number, c?: number) {
return a + b + (c || 0);
}
Default Parameters
For parameters with default values, the default value goes after the type annotation:
Example
function pow(value: number, exponent: number = 10) {
return value ** exponent;
}
TypeScript can also infer the type from the default value.
Named Parameters
Typing named parameters follows the same pattern as typing normal parameters.
Example
function divide({ dividend, divisor }: { dividend: number, divisor: number }) {
return dividend / divisor;
}
Rest Parameters
Rest parameters can be typed like normal parameters, but the type must be an array as rest parameters are always arrays.
Example
function add(a: number, b: number, ...rest: number[]) {
return a + b + rest.reduce((p, c) => p + c, 0);
}
Type Alias
Function types can be specified separately from functions with type aliases.
These types are written similarly to arrow functions, read more about arrow functions .
Example
type Negate = (value: number) => number;
// in this function, the parameter `value` automatically gets assigned the type `number` from the type `Negate`
const negateFunction: Negate = (value) => value * -1;
TypeScript Exercises
There are times when working with types where it's necessary to override the type of a variable, such as when incorrect types are provided by a library.
Casting is the process of overriding a type.
Casting with as
A straightforward way to cast a variable is using the as keyword,
which will directly change the type of the given variable.
Example
let x: unknown = 'hello';
console.log((x as string).length);
Casting doesn't actually change the type of the data within the variable,
for example the following code will not work as expected since the variable x is still holds a number.
let x: unknown = 4;
console.log((x as string).length); // prints undefined since numbers don't have a length
TypeScript will still attempt to typecheck casts to prevent casts that don't seem correct,
for example the following will throw a type error since TypeScript knows casting a string to a number doesn't makes sense
without converting the data:
console.log((4 as string).length); // Error: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
The Force casting section below covers how to override this.
Casting with <>
Using <> works the same as casting with as.
Example
let x: unknown = 'hello';
console.log((<string>x).length);
This type of casting will not work with TSX, such as when working on React files.
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Force casting
To override type errors that TypeScript may throw when casting, first cast to unknown, then to the target type.
Example
let x = 'hello';
console.log(((x as unknown) as number).length); // x is not actually a number so this will return undefined
TypeScript Exercises
TypeScript adds types and visibility modifiers to JavaScript classes.
Learn more about JavaScript classes .
Members: Types
The members of a class (properties & methods) are typed using type annotations, similar to variables.
Example
class Person {
name: string;
}
const person = new Person();
person.name = "Jane";
Members: Visibility
Class members also be given special modifiers which affect visibility.
There are three main visibility modifiers in TypeScript.
public - (default) allows access to the class member from anywhere
private - only allows access to the class member from within the class
protected - allows access to the class member from itself and any classes that inherit it, which is covered in the inheritance section below
Example
class Person {
private name: string;
public constructor(name: string) {
this.name = name;
}
public getName(): string {
return this.name;
}
}
const person = new Person("Jane");
console.log(person.getName()); // person.name isn't accessible from outside the class since it's private
The this keyword in a class usually refers to the instance of the class.
Read more about this .
Parameter Properties
TypeScript provides a convenient way to define class members in the constructor, by adding a visibility modifiers to the parameter.
Example
class Person {
// name is a private member variable
public constructor(private name: string) {}
public getName(): string {
return this.name;
}
}
const person = new Person("Jane");
console.log(person.getName());
Readonly
Similar to arrays, the readonly keyword can prevent class members from being changed.
Example
class Person {
private readonly name: string;
public constructor(name: string) {
// name cannot be changed after this initial definition, which has to be either at it's declaration or in the constructor.
this.name = name;
}
public getName(): string {
return this.name;
}
}
const person = new Person("Jane");
console.log(person.getName());
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Inheritance: Implements
Interfaces (covered ) can be used to define the type a class must follow through the implements keyword.
Example
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
A class can implement multiple interfaces by listing each one after implements, separated by a comma like so: class Rectangle implements Shape, Colored {
Inheritance: Extends
Classes can extend each other through the extends keyword. A class can only extends one other class.
Example
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
class Square extends Rectangle {
public constructor(width: number) {
super(width, width);
}
// getArea gets inherited from Rectangle
}
Override
When a class extends another class, it can replace the members of the parent class with the same name.
Newer versions of TypeScript allow explicitly marking this with the override keyword.
Example
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
// using protected for these members allows access from classes that extend from this class, such as Square
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
public toString(): string {
return `Rectangle[width=${this.width}, height=${this.height}]`;
}
}
class Square extends Rectangle {
public constructor(width: number) {
super(width, width);
}
// this toString replaces the toString from Rectangle
public override toString(): string {
return `Square[width=${this.width}]`;
}
}
By default the override keyword is optional when overriding a method, and only helps to prevent accidentally overriding a method that does not exist.
Use the setting noImplicitOverride to force it to be used when overriding.
Abstract Classes
Classes can be written in a way that allows them to be used as a base class for other classes without having to implement all the members.
This is done by using the abstract keyword.
Members that are left unimplemented also use the abstract keyword.
Example
abstract class Polygon {
public abstract getArea(): number;
public toString(): string {
return `Polygon[area=${this.getArea()}]`;
}
}
class Rectangle extends Polygon {
public constructor(protected readonly width: number, protected readonly height: number) {
super();
}
public getArea(): number {
return this.width * this.height;
}
}
Abstract classes cannot be directly instantiated, as they do not have all their members implemented.
TypeScript Exercises
Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use.
Generics makes it easier to write reusable code.
Functions
Generics with functions help make more generalized methods which more accurately represent the types used and returned.
This also works with interfaces with the following syntax: interface Wrapped<T> {
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Default Value
Generics can be assigned default values which apply if no other value is specified or inferred.
Example
class NamedValue<T = string> {
private _value: T | undefined;
constructor(private name: string) {}
public setValue(value: T) {
this._value = value;
}
public getValue(): T | undefined {
return this._value;
}
public toString(): string {
return `${this.name}: ${this._value}`;
}
}
let value = new NamedValue('myNumber');
value.setValue('myValue');
console.log(value.toString()); // myNumber: myValue
Extends
Constraints can be added to generics to limit what's allowed. The constraints make it possible to rely on a more specific type when using the generic type.
Record<string, number> is equivalent to { [key: string]: number }
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Omit
Omit removes keys from an object type.
Example
interface Person {
name: string;
age: number;
location?: string;
}
const bob: Omit<Person, 'age' | 'location'> = {
name: 'Bob'
// `Omit` has removed age and location from the type and they can't be defined here
};
Pick
Pick removes all but the specified keys from an object type.
Example
interface Person {
name: string;
age: number;
location?: string;
}
const bob: Pick<Person, 'name'> = {
name: 'Bob'
// `Pick` has only kept name, so age and location were removed from the type and they can't be defined here
};
Exclude
Exclude removes types from a union.
Example
type Primitive = string | number | boolean
const value: Exclude<Primitive, string> = true; // a string cannot be used here since Exclude removed it from the type.
ReturnType
ReturnType extracts the return type of a function type.
Readonly is used to create a new type where all properties are readonly, meaning they cannot be modified once assigned a value.
Keep in mind TypeScript will prevent this at compile time, but in theory since it is compiled down to JavaScript you can still override a readonly property.
Example
interface Person {
name: string;
age: number;
}
const person: Readonly = {
name: "Dylan",
age: 35,
};
person.name = 'Israel'; // prog.ts(11,8): error TS2540: Cannot assign to 'name' because it is a read-only property.
TypeScript Exercises
keyof is a keyword in TypeScript which is used to extract the key type from an object type.
keyof with explicit keys
When used on an object type with explicit keys, keyof creates a union type with those keys.
Example
interface Person {
name: string;
age: number;
}
// `keyof Person` here creates a union type of "name" and "age", other strings will not be allowed
function printPersonProperty(person: Person, property: keyof Person) {
console.log(`Printing person property ${property}: "${person[property]}"`);
}
let person = {
name: "Max",
age: 27
};
printPersonProperty(person, "name"); // Printing person property name: "Max"
keyof with index signatures
keyof can also be used with index signatures to extract the index type.
type StringMap = { [key: string]: unknown };
// `keyof StringMap` resolves to `string` here
function createStringPair(property: keyof StringMap, value: string): StringMap {
return { [property]: value };
}
TypeScript has a powerful system to deal with null or undefined values.
By default null and undefined handling is disabled, and can be enabled by setting strictNullChecks to true.
The rest of this page applies for when strictNullChecks is enabled.
Types
null and undefined are primitive types and can be used like other types, such as string.
Example
let value: string | undefined | null = null;
value = 'hello';
value = undefined;
When strictNullChecks is enabled, TypeScript requires values to be set
unless undefined is explicitly added to the type.
Optional Chaining
Optional Chaining is a JavaScript feature that works well with TypeScript's null handling.
It allows accessing properties on an object, that may or may not exist, with a compact syntax.
It can be used with the ?. operator when accessing properties.
Example
interface House {
sqft: number;
yard?: {
sqft: number;
};
}
function printYardSize(house: House) {
const yardSize = house.yard?.sqft;
if (yardSize === undefined) {
console.log('No yard');
} else {
console.log(`Yard is ${yardSize} sqft`);
}
}
let home: House = {
sqft: 500
};
printYardSize(home); // Prints 'No yard'
Nullish Coalescence
Nullish Coalescence is another JavaScript feature that also works well with TypeScript's null handling.
It allows writing expressions that have a fallback specifically when dealing with null or undefined.
This is useful when other falsy values can occur in the expression but are still valid.
It can be used with the ?? operator in an expression, similar to using the && operator.
Example
function printMileage(mileage: number | null | undefined) {
console.log(`Mileage: ${mileage ?? 'Not Available'}`);
}
printMileage(null); // Prints 'Mileage: Not Available'
printMileage(0); // Prints 'Mileage: 0'
Get Certified!
Complete the TypeScript modules, do the exercises, take the exam and become w3schools certified!!
Null Assertion
TypeScript's inference system isn't perfect, there are times when it makes sense to ignore a value's
possibility of being null or undefined.
An easy way to do this is to use casting, but TypeScript also provides the ! operator as a convenient shortcut.
Example
function getValue(): string | undefined {
return 'hello';
}
let value = getValue();
console.log('value length: ' + value!.length);
Just like casting, this can be unsafe and should be used with care.
Array bounds handling
Even with strictNullChecks enabled, by default TypeScript will assume array access will never return undefined (unless undefined is part of the array type).
The config noUncheckedIndexedAccess can be used to change this behavior.
Example
let array: number[] = [1, 2, 3];
let value = array[0]; // with `noUncheckedIndexedAccess` this has the type `number | undefined`
NPM packages in the broad JavaScript ecosystem doesn't always have types available.
Sometimes the projects are no longer maintained, and other times they aren't interested in, agree with, or have time to use TypeScript.
Using non-typed NPM packages in TypeScript
Using untyped NPM packages with TypeScript will not be type safe due to lack of types.
To help TypeScript developers use such packages, there is a community maintained project called .
Definitely Typed is a project that provides a central repository of TypeScript definitions for NPM packages which do not have types.
Example
npm install --save-dev @types/jquery
No other steps are usually needed to use the types after installing the declaration package, TypeScript will automatically pick up the types when using the package itself.
Editors such as Visual Studio Code will often suggest installing packages like these when types are missing.
TypeScript is actively maintained and updated by Microsoft. In version 5.x a lot of utility and quality of life updates were made.
This chapter covers the most popular updates to allow stricter and more flexible type safety.
As a reminder these features will only be available in 5.x+
Template Literal Types
Template Literal Types now allows us to create more precise types using template literals. We can define custom types that depend on the actual values of strings at compile time.
Example
type Color = "red" | "green" | "blue";
type HexColor = `#${string}`;
// Usage:
let myColor: HexColor<"blue"> = "#0000FF";
Index Signature Labels
Index Signature Labels allows us to label index signatures using computed property names. It helps in providing more descriptive type information when working with dynamic objects.
Example
type DynamicObject = { [key: string as `dynamic_${string}`]: string };
// Usage:
let obj: DynamicObject = { dynamic_key: "value" };
5.x also now supports native JavaScript private fields. The TypeScript 'private' still works as discussed in section.
TypeScript Online Editor
TypeScript Editor
With our online TypeScript editor, you can edit TypeScript code, and view the result in your browser.
Size:
Example
console.log('Hello World!');
Hello World!
Click on the "Try it Yourself" button to see how it works.
Publish Your Code
If you want to create your own website or build TypeScript applications, check out .
is a website-building tool that enables you to create and share your own website, as well as develop and host your TypeScript applications within a Node.js environment.
You have full control over the website's appearance and functionality by editing the code directly in your web browser.
The tool is user-friendly and requires no setup, making it easy to use.
The code editor is packed with features to help you achieve more:
Templates: Start from scratch or use a template
Cloud-based: no installations required. You only need your browser
Terminal & Log: debug and troubleshoot your code easily
File Navigator: switch between files inside the code editor
And much more!
Learn Faster
Practice is key to mastering coding, and the best way to put your TypeScript knowledge into practice is by getting practical with code.
Use to build, test and deploy code.
The code editor lets you write and practice different types of computer languages. It includes TypeScript, and you can use it for other languages too.
New languages are added all the time:
If you don't know TypeScript, we suggest that you read our from scratch.
If you don't know Node.js, we suggest that you read our from scratch.
Build Powerful Websites
You can also use the code editor in to build frontend or full-stack websites from scratch.
Or you can use the 60+ templates available and save time:
Create your Spaces account today and explore them all!
Share It With The World
Host and publish your websites in no time with .
W3Schools subdomain and SSL certificate are included for free with . An SSL certificate makes your website safe and secure. It also helps people trust your website and makes it easier to find it online.
Want a custom domain for your website?
You can buy a domain or transfer an existing one and connect it to your space.
How Does It Work?
Get started in a few clicks with .
You can test your TypeScript skills with W3Schools' Exercises.
Exercises
We have gathered a variety of TypeScript exercises (with answers) for each chapter.
Try to solve an exercise by filling in the missing parts of a code. If you're stuck, hit the "Show Answer" button to see what you've done wrong.
Count Your Score
You will get 1 point for each correct answer. Your score and total score will always be displayed.
Start TypeScript Exercises
Good luck!
If you don't know TypeScript, we suggest that you read our from scratch.
TypeScript Quiz
You can test your TypeScript skills with W3Schools' Quiz.
The Test
The test contains 25 questions and there is no time limit.
The test is not official, it's just a nice way to see how much you know, or don't know, about TypeScript.
Count Your Score
You will get 1 point for
each correct answer. At the end of the Quiz, your total score will be displayed.
Maximum score is 25 points.
Start the Quiz
Good luck!
If you don't know TypeScript, we suggest that you read our from scratch.
TypeScript Certificate
W3Schools offers an Online Certification Program.
The perfect solution for busy professionals who need to balance work, family, and career building.
More than 50 000 certificates already issued!
W3Schools offers an Online Certification Program.
The perfect solution for busy professionals who need to balance work, family, and career building.
More than 50 000 certificates already issued!
Document your skills Improve your career
Study at your own pace Save time and money
Known brand Trusted by top companies
Who Should Consider Getting Certified?
Any student or professional within the digital industry.
Certifications are valuable assets to gain trust and demonstrate knowledge to your clients, current or future employers on a ever increasing competitive market.
W3Schools is Trusted by Top Companies
W3Schools has over two decades of experience with teaching coding online.
Our certificates are recognized and valued by companies looking to employ skilled developers.
Save Time and Money
Show the world your coding skills by getting a certification.
The prices is a small fraction compared to the price of traditional education.
Document and validate your competence by getting certified!
Exam overview
Fee: 95 USD
Number of questions: 70
Requirement to pass: 75% correct answers
Time limit: 70 minutes
Number of attempts to pass: Two
Exam deadline: None
Certification Expiration: None
Format: Online, multiple choice
Advance Faster in Your Career
Getting a certificate proves your commitment to upgrading your skills.
The certificate can be added as credentials to your CV, Resume, LinkedIn profile, and so on.
It gives you the credibility needed for more responsibilities, larger projects, and a higher salary.
Knowledge is power, especially in the current job market.
Documentation of your skills enables you to advance your career or helps you to start a new one.
How Does It Work?
Study for free at W3Schools.com
Study at your own speed
Test your skills with W3Schools online quizzes
Apply for your certificate by paying an exam fee
Take your exam online, at any time, and from any location
Get Your Certificate and Share It With The World
Example certificate:
Each certificate gets a unique link that can be shared with others.
Validate your certification with the link or QR code.
Check how it looks like in this .
Share your certificate on LinkedIn in the Certifications section in just one click!
Document Your Skills
Getting a certificate proves your commitment to upgrade your skills,
gives you the credibility needed for more responsibilities, larger projects, and a higher salary.
Looking to add multiple users?
Are you an educator, manager or business owner looking for courses or certifications?
We are working with schools, companies and organizations from all over the world.