Building with TypeScript: A Lego-Based Guide
TypeScript: The smooth transition from JavaScript to TypeScript is like upgrading your Lego building process!
“Do what you can, use what you have” – this is one of my mottos. This sentence also reflects part of the growth mindset. Most of us front-end or JavaScript developers have already started or completely migrated to TypeScript. But some people may still have difficulty understanding the concepts, or switching their mindset from JavaScript to TypeScript. To solve this problem, we're going to use one of my favorite tools: Legos. Let’s start here: “Think of JavaScript as a basic set of Lego bricks that you can build freely; TypeScript is the same set of bricks, but with detailed instructions and quality control checks.” For a more in-depth discussion of TypeScript, you can refer to here , here , and this video . This guide aims to show how each JavaScript concept translates to TypeScript, using Lego analogies to help you understand the concepts more easily.
Variable Scope and Hoisting: Building a Room
Concept definition
Variable scope refers to the context in which variables can be accessed and used in a program. There are two main types of scope: local scope and global scope. A variable declared outside any function is in global scope, which means it can be accessed and modified anywhere in the code. On the other hand, variables declared inside a function are in local scope and can only be accessed within that function. JavaScript uses the var
, let
, and const
keywords to declare variables, and each keyword has a different impact on the scope. Variables declared with let
and const
are block scoped, which means they can only be accessed within the nearest enclosing block {}
. In contrast, var
is function-scoped, making it available throughout the function in which it is declared. A clear understanding of variable scope helps avoid problems such as variable name conflicts and unexpected side effects in JavaScript programs.
Hoisting is the act of moving variable and function declarations to the top of their containing scope before the code is executed (compilation phase). This means that variables and functions can be used before they are declared. Function declarations are fully hoisted, allowing them to be called even before they are defined in the code. However, variables declared with var
are hoisted but not initialized to their initial value, so accessing them before assignment will result in undefined
. Variables declared with let
and const
are also hoisted but not initialized, which would result in ReferenceError
if accessed before declaration. Understanding promotion helps developers avoid common pitfalls by constructing variable and function declarations correctly.
Lego analogy
Think of scopes as different Lego rooms:
- Global scope: All builders can access the shared living room of the building blocks.
- Function scope: personal building table.
- Block Scope: Build a specific area of the table.
JavaScript implementation
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript Evolution
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
Functions and Closures: Building Instructions
Concept definition
Functions are reusable blocks of code designed to perform a specific task. This enhances modularity and code efficiency. They can be defined using the function
keyword, followed by a name, brackets ()
and a block of code enclosed in curly brackets {}
. Arguments can be passed into a function within parentheses or braces, which act as placeholders for the values provided when the function is called. JavaScript also supports anonymous functions (without names) and arrow functions (providing a cleaner syntax). Functions can use the return
statement to return a value, or perform operations that do not return a value. Additionally, functions in JavaScript are first-class objects, which means they can be assigned to variables, passed as arguments, and returned from other functions, thus enabling the functional programming pattern.
Closures are a powerful feature that allow a function to remember and access its lexical scope even if the function executes outside that scope. Closures can be created when a function is defined inside a function and references variables in the outer function. Even after the outer function has finished executing, the inner function can still access these variables. This feature is useful for data encapsulation and maintaining state in environments such as event handlers or callbacks. Closures support patterns such as private variables, where functions can expose specific behavior while hiding implementation details.
Lego analogy
- Functions are like building instructions.
- Parameters are like required building blocks.
- The return value is like a completed structure.
- A closure is like a sealed building kit with a few permanently included building blocks.
JavaScript implementation
function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }
TypeScript Evolution
// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }
Objects and Prototypes: Building Tips
Concept definition
Objects in JavaScript are basic data structures that serve as containers for related data and functionality. They consist of key-value pairs, where each key (property) maps to a value, which can be any valid JavaScript type, including functions (methods). Objects can be created in several ways:
- Object literal:
const obj = {}
- Constructor:
new Object()
Object.create()
Method
The prototype system is JavaScript’s built-in inheritance mechanism. Every object has an internal link to another object, called its prototype. When trying to access a property that doesn't exist on an object, JavaScript automatically looks for it in its prototype chain. This object chain continues until it reaches an object with the null
prototype, usually Object.prototype
. Understanding prototypes is critical to:
- Implement inheritance
- Sharing methods between instances
- Manage memory efficiency
- Build object hierarchy
Lego analogy
Think of objects and prototypes like this:
- Objects are like dedicated LEGO kits with their own unique bricks and instructions.
- A prototype is like a master template that multiple kits can reference.
- Inheritance is like having a basic suite from which more advanced suites can be built.
- Properties are like specific building blocks in each kit.
- Methods are like special building tips included in each kit.
JavaScript implementation
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript Evolution
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
Asynchronous Programming: Building a Team
Concept definition
Asynchronous functions and programming
Asynchronous functions are a special function type in JavaScript that provide an elegant way to handle asynchronous operations. When declared with the async
keyword, these functions automatically return a Promise and enable the use of the await
keyword in their body. The await
operator pauses the execution of a function until the Promise is resolved or rejected, allowing asynchronous code to be written in a more synchronous and readable style. This syntax effectively reduces the complexity of callbacks and eliminates the need for nested Promise chains. For example, in async function fetchData() { const response = await fetch(url); }
, the function waits for the fetch
operation to complete before continuing execution, making the behavior of the code more predictable while ensuring that the main thread remains unblocked. This pattern is particularly useful when dealing with multiple asynchronous operations that depend on each other, because it allows developers to write code that clearly expresses the order of operations without sacrificing performance.
Promise
Promise represents a value that may be available now, available in the future, or never available. It is an object with three possible states: Pending, Completed, or Rejected. It is used to handle asynchronous operations. Promises have methods such as .then()
, .catch()
and .finally()
for chaining actions based on the result. This makes them a powerful alternative to nested callbacks, improving code readability and error handling.
Lego analogy
- Asynchronous functions are like team members working on different parts.
- Promise is like an agreement to deliver the completed part.
JavaScript implementation
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript Evolution
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
Modern Features: Advanced Building Techniques
Concept definition
Deconstruction
This is a neat way to extract values from an array or properties from an object into different variables. Array destructuring uses square brackets []
, while object destructuring uses curly brackets {}
. This syntax reduces the need for duplicate code by unpacking values directly into variables, making it easier to handle complex data structures. For example, const [a, b] = [1, 2]
assigns 1 to a and 2 to b, while const { name } = person
extracts the name attribute from the person object.
Expand operator
The spread operator is represented by three dots (...). It allows iterable objects such as arrays or objects to be extended where multiple elements or key-value pairs are required. It can be used to copy, combine, or pass array elements as function arguments. For example, const arr = [1, 2, ...anotherArray]
.
Optional chain
Optional chains are represented by ?.
. It provides a safe way to access deeply nested object properties without causing errors when the property is undefined or null. If the reference is nullish, it short-circuits and returns undefined immediately. For example, user?.address?.street
checks if user and address exist before accessing street. This syntax prevents runtime errors and makes working with nested data structures cleaner and less error-prone, especially in APIs or data that relies on user input.
Lego analogy
- Deconstruction is like sorting building blocks into containers.
- The spread operator is like copying building blocks between suites.
- Optional chaining is like checking if a block exists before using it.
JavaScript implementation
function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }
TypeScript Evolution
// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }
Summary
The transition from JavaScript to TypeScript is like upgrading your Lego building process:
-
JavaScript (basic construction):
- Free-form construction
- Flexible use of building blocks
- Runtime error detection
-
TypeScript (professionally built):
- Detailed and specific instructions
- Brick Compatibility Check
- Error prevention before construction
Key transition tips:
- Start with basic type annotations.
- Add interfaces and type definitions gradually.
- Use the compiler to catch errors early.
- Use type inference whenever possible.
- Strict null checking and other compiler options are gradually added.
Remember: TypeScript builds on your JavaScript knowledge, adding security and clarity, rather than changing the fundamental building process. That said, my advice is still... learn JavaScript first, then learn TypeScript.
References
-
Retrieved January 12, 2025, from
- https://www.php.cn/link/84b184211c5d929d9435a371eb505cad Mozilla. (n.d.). Variables — JavaScript . MDN Web Docs. Retrieved January 14, 2025, from
- https://www.php.cn/link/646e69d6e105d351e4e31a2e02a69b0e
The above is the detailed content of Building with TypeScript: A Lego-Based Guide. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing
