# TypeScript --- Beginner to Intermediate Study Notes

2026-11-10来源 dev.to TypeScriptEnglish

A practical, easy-to-follow guide from JavaScript to TypeScript

These notes follow the topics in the uploaded TypeScript Full Course
PDF. I've rewritten the explanations in a more natural, student-friendly
way and kept the examples close to the original material.

1. What is TypeScript?

TypeScript is JavaScript with an extra layer of type checking.

In JavaScript, a variable can hold different kinds of values as your
program runs. That flexibility is useful, but it can also lead to
mistakes that are difficult to spot.

TypeScript lets us describe what kind of value a variable should
contain. It checks those rules while we are writing and compiling the
code.

One important thing to remember: TypeScript does not run directly in
the browser or Node.js.
It is compiled into JavaScript first. The type
annotations are removed during compilation, and the resulting JavaScript
can run wherever JavaScript is supported.

JavaScript vs TypeScript

// JavaScript let age = 22; age = "Twenty Two"; // JavaScript allows this 
// TypeScript let age: number = 22; age = "Twenty Two"; // TypeScript reports an error 

Because age is declared as a number, TypeScript warns us when we try
to assign a string.

Why use TypeScript?

  • It catches many type-related mistakes before the program runs.
  • It gives better autocomplete and IntelliSense in editors such as VS Code.
  • It makes code easier to understand because the expected data is clearly described.
  • It makes refactoring safer, especially in larger projects.
  • It helps teams maintain code over time.

2. Installing TypeScript

TypeScript is available as an npm package. For a normal project, install
it locally as a development dependency.

mkdir typescript-course cd typescript-course npm init -y npm install --save-dev typescript npx tsc --version npx tsc --init npx tsc 

What do these commands do?

Command Purpose

mkdir typescript-course Creates a folder for the project.

cd typescript-course Moves into that folder.

npm init -y Creates a package.json with
default settings.

npm install --save-dev typescript Installs TypeScript as a
development dependency.

npx tsc --version Shows the installed TypeScript
compiler version.

npx tsc --init Creates a tsconfig.json
configuration file.

npx tsc Runs the TypeScript compiler using
the project configuration.

The TypeScript compiler is called tsc. It checks and compiles
TypeScript files into JavaScript.

3. Data Types

Why do types matter?

JavaScript allows a variable to change from one type to another:

let username = "Rohith"; username = 100; username = true; 

This can become confusing in a larger application. For example, a
function may expect a string but accidentally receive a number.

TypeScript helps us catch this kind of mismatch.

let username: string = "Rohith"; 

Now username must contain a string. Assigning a number or boolean will
produce a type error.

Common primitive and basic types

Type What it represents Example

string Text "Rohith"

number Integers and decimal 25, 10.5
numbers

boolean True or false true

any Disables type checking let value: any = "hello"
for that value

unknown A value whose type is let value: unknown = "hello"
not known yet

void Usually means a function log(): void {}
function does not

return a value

null An intentional absence null
of a value

undefined A value that has not undefined
been assigned

any vs unknown

Both can hold values of different types, but they behave differently.

With any, TypeScript allows us to use the value without checking its
type:

let value: any = "Hello"; console.log(value.toUpperCase()); 

With unknown, TypeScript asks us to check the type before using
type-specific operations:

let value: unknown = "Hello"; if (typeof value === "string") { console.log(value.toUpperCase()); } 

Practical takeaway: Prefer a specific type whenever you know what
the value should be. If you genuinely do not know the type yet,
unknown is safer than any.

4. Functions

TypeScript allows us to specify the types of function parameters and the
value a function returns.

Basic typed function

function add(a: number, b: number): number { return a + b; } 

Here:

  • a: number means the first parameter must be a number.
  • b: number means the second parameter must be a number.
  • : number after the parentheses means the function returns a number.

Optional parameters

A question mark makes a parameter optional. The caller can leave it out.

function greet(name: string, age?: number): string { if (age !== undefined) { return `${name} is ${age} years old`; } return `Hello, ${name}`; } 

Both of these calls are valid:

greet("Rohith"); greet("Rohith", 22); 

Default parameters

A default value is used when the caller does not provide that argument.

function greet(name: string, greeting: string = "Hello"): string { return `${greeting}, ${name}`; } greet("Rohith"); greet("Rohith", "Good morning"); 

Rest parameters

Use ... when a function should accept any number of arguments. In this
example, all the extra arguments must be numbers.

function sumAll(...numbers: number[]): number { return numbers.reduce((total, n) => total + n, 0); } sumAll(10, 20, 30); 

Arrow functions

Arrow functions can also have typed parameters and return values.

const add = (a: number, b: number): number => a + b; 

Returning arrays and objects

You can describe the shape of the value returned by a function.

function getCoordinates(): [number, number] { return [10, 20]; } function getUser(): { id: number; name: string } { return { id: 1, name: "Rohith" }; } 

Remember: Typing function inputs and outputs makes it clearer what a
function accepts and what other parts of the program can expect from it.

5. Arrays and Objects

Typed arrays

A regular array can contain many values. In TypeScript, we can specify
the type of its elements.

const scores: number[] = [80, 90, 95]; const names: string[] = ["Rohith", "Anu"]; 

Arrays of objects

We can describe the structure each object in an array must follow.

const users: { id: number; name: string }[] = [ { id: 1, name: "Rohith" }, { id: 2, name: "Anu" } ]; 

Each item must have an id that is a number and a name that is a
string.

Readonly arrays

A readonly array cannot be changed through operations such as push or
pop.

const ids: readonly number[] = [1, 2, 3]; 

Use this when you want to prevent accidental changes to an array.

Nested objects

Object types can contain other object types. A type alias can make
nested structures easier to read.

type Address = { city: string; zip: string; }; type User = { id: number; name: string; address: Address; }; 

Tuples

A tuple is an array with a fixed order and a specific type for each
position.

let point: [number, number] = [10, 20]; let entry: [string, number] = ["Rohith", 25]; 

For entry, the first position must be a string and the second must be
a number.

Array vs tuple: An ordinary typed array usually allows multiple
elements of the same type. A tuple describes the expected type at each
position.

6. Type Aliases

A type alias gives a reusable name to a type. It is especially helpful
when the same object structure appears in different parts of a project.

type User = { id: number; name: string; }; const user: User = { id: 1, name: "Rohith" }; 

Instead of writing { id: number; name: string } every time, we can
simply use User.

If the structure needs to change, we can update the alias in one place.

7. Type Aliases for Functions

A type alias can describe a function's parameters and return type too.

type Add = (a: number, b: number) => number; const add: Add = (a, b) => a + b; 

The Add type says that the function must accept two numbers and return
a number. TypeScript can infer the types of a and b from the alias.

This is useful for reusable function signatures, callbacks and event
handlers.

8. Union Types

A union type allows a value to be one of a few specified types. The |
symbol means "or".

type UserId = number | string; let id: UserId = 101; id = "EMP001"; 

The value can be a number or a string, but not a boolean.

When using a union, check which type you have before calling an
operation that only works for one of those types.

function printId(id: number | string): void { if (typeof id === "string") { console.log(id.toUpperCase()); } else { console.log(id.toFixed(0)); } } 

This type-checking process is called type narrowing.

9. Intersection Types

An intersection combines multiple types. The & symbol means the
resulting value must satisfy all the combined types.

type Person = { name: string; }; type Employee = { salary: number; }; type Staff = Person & Employee; const staff: Staff = { name: "Rohith", salary: 50000 }; 

A Staff object must contain both name and salary.

Union vs intersection

  • A | B: the value can be either type A or type B.
  • A & B: the value must satisfy both type A and type B.

10. Primitive Type Aliases

You can give a primitive type a more meaningful name.

type Username = string; let name: Username = "Rohith"; 

Username behaves just like string. The benefit is readability: the
name communicates what the value represents.

11. Interfaces

An interface describes the shape of an object. It is commonly used to
define the structure of objects and classes.

interface Student { id: number; name: string; } const student: Student = { id: 1, name: "Rohith" }; 

Optional properties

Add ? when a property is not required.

interface Student { id: number; name: string; email?: string; } 

An object can follow this interface even if it does not have an email
property.

Readonly properties

Use readonly when a property should not be reassigned after the object
is created.

interface Student { readonly id: number; name: string; } const student: Student = { id: 1, name: "Rohith" }; // student.id = 2; // TypeScript error 

Extending interfaces

An interface can extend another interface and reuse its properties.

interface Person { name: string; } interface Employee extends Person { salary: number; } 

An Employee must have both name and salary.

Interface vs type alias

Both can describe object shapes, and they are often interchangeable for
that purpose.

Interface Type alias

Commonly used to describe object Can describe objects, unions,
and class shapes. intersections, tuples and
primitives.

Can extend another interface using Can combine types using
extends. intersections (&).

Supports declaration merging. Does not support declaration
merging.

A useful starting point is to use interfaces for object shapes that may
be extended, and type aliases when you need unions, intersections or
other kinds of types.

12. Enums

An enum gives names to a fixed set of related values. This can make code
easier to read than using unexplained numbers or strings.

enum Role { Admin, User, Guest } let role: Role = Role.Admin; 

Numeric enums

By default, numeric enum values start at 0 and increase by one:

  • Admin is 0.
  • User is 1.
  • Guest is 2.

You can also assign custom numeric values.

String enums

String enums use readable string values.

enum Status { Active = "ACTIVE", Inactive = "INACTIVE" } 

These values can be clearer when they are logged or sent in data.

Heterogeneous enums

An enum can technically contain both numbers and strings:

enum Mixed { No = 0, Yes = "YES" } 

This is generally discouraged because mixing value types can make the
code less consistent.

Enum vs union type

Enums exist as objects at runtime. A union of string literal types is
removed during compilation and does not create an enum object.

For simple fixed string choices, a union can be a lightweight option:

type Status = "ACTIVE" | "INACTIVE"; let currentStatus: Status = "ACTIVE"; 

13. Generic Functions

Generics allow a function to work with different types without losing
information about the type it receives.

The problem without generics

A function without a clear type can lose useful type information.

function identity(value: any): any { return value; } 

Using any means TypeScript cannot properly preserve the relationship
between the input and output types.

The generic solution

function identity<T>(value: T): T { return value; } 

Here, T is a type parameter --- a placeholder for the type supplied
when the function is used.

const numberValue = identity(5); // number const stringValue = identity("hello"); // string 

TypeScript infers T from the argument. The function works with
different types while keeping the input and output types connected.

14. Generic Interfaces

Interfaces can use type parameters too. This makes it possible to reuse
the same structure with different kinds of data.

interface ApiResponse<T> { data: T; success: boolean; } 

For example, the same interface can describe a response containing a
user or a list of products.

type User = { id: number; name: string; }; const userResponse: ApiResponse<User> = { data: { id: 1, name: "Rohith" }, success: true }; 

The T in ApiResponse<T> is replaced by the type provided when the
interface is used.

15. Generic Constraints (extends)

Sometimes a generic function needs a value to have a particular
property. A generic constraint lets us set that requirement.

function printLength<T extends { length: number }>(value: T): void { console.log(value.length); } 

This function accepts values that have a numeric length property.

For example, strings and arrays have a length property, so they can be
passed to the function. A plain number does not have that property, so
it does not satisfy the constraint.

The key idea: generics keep a function flexible, while extends limits
the types to values that support the operations the function needs.

16. keyof with Generics

The keyof operator creates a type containing the property names of
another type.

It becomes especially useful with generics when we want to access an
object's properties safely.

function getValue<T, K extends keyof T>(obj: T, key: K) { return obj[key]; } const user = { id: 1, name: "Rohith" }; const value = getValue(user, "name"); // inferred as string 

In this example, the valid keys are "id" and "name". Passing a
property name that does not exist on the object produces a type error.

This pattern is useful when building reusable helper functions that read
values from objects.

17. tsconfig.json

The tsconfig.json file controls how the TypeScript compiler checks and
compiles a project.

A simple example based on the course notes:

{ "compilerOptions": { "target": "esnext", "module": "nodenext", "strict": true } } 

Important options

Option What it controls

target The JavaScript version TypeScript should output.
module The module system used by the compiled output.
strict Enables stricter type-checking rules.

The tsconfig.json file is created using npx tsc --init. You can then
adjust the compiler options to suit your project.

Important: The course notes recommend enabling strict because it
helps catch more mistakes during development.

18. Modules: Import and Export

Modules let us split code into separate files and reuse functions,
variables and types.

CommonJS

This is the traditional Node.js module syntax:

const math = require("./math"); module.exports = {}; 

ES Modules

Modern JavaScript and TypeScript commonly use export and import.

// math.ts export function add(a: number, b: number) { return a + b; } 
// app.ts import { add } from "./math.js"; console.log(add(10, 20)); 

export makes something available to other files. import brings it
into the current file.

The example uses ./math.js in the import path even though the source
file is math.ts. In the Node.js module setup described by the course,
this path refers to the JavaScript file that will exist after
compilation.

Final Revision: What should you remember?

Topic Main idea

TypeScript JavaScript with static type
checking.

Data types Describe what kind of values
variables can hold.

Functions Type parameters and return values.

Arrays and objects Define the expected structure of
data.

Tuples Fix the type and order of array
positions.

Type aliases Give reusable names to types.

Union (\|) Allow one of several types.

Intersection (&) Combine multiple types into one
requirement.

Interfaces Describe object structures and
support extension.

Enums Give names to a fixed set of
values.

Generics Reuse code with different types
while preserving type information.

Constraints Restrict generic types to values
with a required shape.

keyof Get the property names of a type.

tsconfig.json Configure the TypeScript compiler.

Modules Share code using imports and
exports.

A sensible order for practising

If you are learning TypeScript for the first time, try this order:

  1. Practise primitive types and typed variables.
  2. Write functions with typed parameters and return values.
  3. Create typed arrays and object shapes.
  4. Practise type aliases and interfaces.
  5. Understand unions and intersections.
  6. Try enums and generic functions.
  7. Practise generic interfaces, constraints and keyof.
  8. Read the tsconfig.json file and experiment with imports and exports.

The best way to learn these topics is to write small examples yourself,
intentionally make a type mistake, and see how TypeScript reports it.

These notes are a human-friendly rewrite of the uploaded course
material. The examples and topics follow that source; they are intended
as study notes rather than a complete reference for every TypeScript
feature.

原文:https://www.a8q9.cn/en/article/typescript-beginner-to-intermediate-study-notes-20984a.html

相关文章