likes
comments
collection
share

一边学技术一边学英语系列———Stirring Up (刺激起) Some TypeScript Magic(魔力)

作者站长头像
站长
· 阅读数 14
一边学技术一边学英语系列———Stirring Up (刺激起) Some TypeScript Magic(魔力)

Stirring Up 【刺激起】 Some TypeScript Magic【魔力】

原文地址:double-trouble.dev/post/typesc…

对于很多TypeScript的开发者来说,小的增强辅助函数,可以明显的提高代码的可读性可维护性。这篇博客致力于向你介绍5个必不可少的TypeScript技巧辅助函数,目的在于易于复制粘贴到你的代码库中。

For TypeScript developers, small enhancements and helper functions can significantly improve code readability and maintainability. This blog post is dedicated to providing you with five essential TypeScript tips and helper functions, designed to be easily copied and pasted into your codebase.

开搞吧!

Let’s dive in.

技巧一:使用空合并操作符(??)抛出内联异常

Inline Error Raising with the Nullish Coalescing Operator

很多时候,我们发现自己需要抛出一个错误,如果一个特定的值为null或undefined。

Many times, we find ourselves needing to throw an error if a particular value is null or undefined.

TypeScript不需要手动检查,而是提供了一种使用空合并操作符(??)和一个简单的辅助函数来内联这个过程的方法。

Instead of checking this manually, TypeScript provides a way to inline this process using the nullish coalescing operator (??) and a simple helper function.

const raise = (err: string) : never => { throw new Error(err);};

当这个'raise'函数与null合并运算符结合使用时,可以让你编写出可读性更强、更简洁的代码。

This ‘raise’ function, when coupled with the nullish coalescing operator, allows you to write more readable and concise code.

const Page = (props: { params: { id?: string }}) => {
    const id = props.params.id ?? raise('No id provided');
};

因为这个令人惊讶的技巧,要向TypeScript布道者Matt Pocock和@HeyImMapleLeaf(最初发布)喊话,表示感谢。

Shout-out to the TypeScript Wizard himself Matt Pocock and @HeyImMapleLeaf (originally posted) for this amazing tip.

技巧二: 使用 映射类型

Utilizing Mapped Types

映射类型是TypeScript的一个强大 特性,它允许你基于 现有类型创建新类型。

Mapped Types is a powerful TypeScript feature that allows you to create new types based on existing ones.

它们可以帮助您保持类型不冗余(don't repeat youself)减少重复提高可维护性

They can help you to keep your types DRY, reducing duplication and improving maintainability.

Readonly 只读的

映射类型的一个常见示例是Readonly。

A common example of a Mapped Type is Readonly.

这使得T的所有属性都是只读的:

This makes all properties of T read-only:

interface IUser {
    name: string;
    age: number;
}

type ReadonlyUser = Readonly<IUser>;

现在ReadonlyUser的所有属性都是只读的

Now, all properties of ReadonlyUser are read-only.

Partial 部分属性

另一个方便的映射类型是Partial,它使T的所有属性都是可选的:

Another handy Mapped Type is Partial, which makes all properties of T optional:

interface IUser {
    name: string;
    age: number;
}

type PartialUser = Partial<IUser>;

// PartialUser类型:
{ 
    name?: string, 
    age?: number 
}

Record 记录

Record<K,T> Mapped Type可以用来创建一个属性键为K,属性值为T的对象类型:

The Record<K,T> Mapped Type can be used to create an object type where the property keys are K and the property values are T:

type UserRecord = Record<string, IUser>;

UserRecord现在是一个对象类型,可以接受任何字符串作为键,但是值必须是 IUser类型

UserRecord is now an object type that will accept any string as a key, and any value must be of type IUser.

创建自己的映射类型 Creating Your Own Mapped Types

你可以不仅仅局限于TypeScript提供的映射类型。

You’re not just limited to the Mapped Types that TypeScript provides.

也可以创建自己的映射类型:

You can also create your own:

type Nullable<T> = { [P in keyof T]: T[P] | null };

这个Nullable类型接受一个现有类型T,并产生一个新类型,其中每个属性都可为空

This Nullable type takes an existing type T, and produces a new type where every property is nullable.

映射类型帮助您在现有类型的基础上创建复杂类型减少代码重复增强类型安全性

Mapped types help you to create complex types based on your existing ones, reducing code duplication and enhancing type safety.

技巧三:Type Guarding 类型保护

TypeScript支持用户自定义类型保护来收缩 条件判断中对象的类型。

TypeScript supports user-defined type guards to narrow down the type of an object within a conditional block.

这是通过使用返回布尔值的函数来实现的,布尔值指示对象是否属于 特定类型。

This is achieved by using a function that returns a boolean, indicating whether the object is of a specific type.

function isString(test: any): test is string {

    return typeof test === "string";

}

function printLength(input: string | any[]) {

    if (isString(input)) {

        console.log(input.length);

    } else {

        console.log(input.length);

    }

}

在本例中,isString函数是一个类型保护确保if判断中将输入作为字符串处理

In this example, isString is a type guard that ensures input is treated as a string within the if block.

技巧四:Strongly-Typed Event Emitters 强类型事件发射器

在需要使用事件驱动 架构的场景下,可能需要使用事件发射器

In cases where you need to use an event-driven architecture, you might need to use an event emitter.

JavaScript内置事件发射器的缺点是它不是强类型的。

The downside of JavaScript’s built-in event emitter is that it’s not strongly typed.

不用担心,TypeScript正可以挽狂澜于既倒 扶大厦之将倾

But fear not, TypeScript is here to save the day.

import { EventEmitter } from "events";

interface MyEvents {

    event1: (param1: string, param2: number) => void;

    event2: () => void;

}

class MyEventEmitter extends EventEmitter {

    public emit<T extends keyof MyEvents>(event: T,...args: Parameters<MyEvents[T]>) {

        return super.emit(event, ...args);
    }

    public on<T extends keyof MyEvents>(event: T, listener: MyEvents[T]): this {

        return super.on(event, listener);
    }

}

const myEmitter = new MyEventEmitter();

myEmitter.on('event1', (param1, param2) => {

    // 类型安全的参数!
    // Type-safe parameters!

});

有了这段代码,您就可以使用完全类型安全的事件发射器了! With this code, you can enjoy a fully type-safe event emitter!

技巧五 Enforcing Readonly Properties 强制执行只读属性

TypeScript有readonly修饰符可以很容易地创建那些设置好后就不能修改的属性。

TypeScript has the readonly modifier, making it easy to create properties that can’t be changed after they’re set.

这对于创建具有不可改变的属性的对象特别有用。

This can be particularly useful for creating objects with properties that should never change.

interface Config {
    readonly apiUrl: string;
    readonly defaultTimeout: number;
}

const config: Config = {
    apiUrl: "https://myapi.com",
    defaultTimeout: 5000,
};

config.apiUrl = "https://anotherapi.com";
// 错误!
// Error!

在这个例子中,任何改变apiUrl或defaultTimeout的尝试都会导致TypeScript报错。

In this example, any attempts to change the apiUrl or defaultTimeout will result in a TypeScript error.

The End 结束语

这些只是TypeScript提供的特性能力几个例子旨在 加快你的开发进度

These are just a few examples of the features and techniques TypeScript offers to enhance your development process.

有了这些技巧和辅助函数,您的代码将更干净、更安全、更易于维护

With these tips and helper functions, your code will be cleaner, safer, and easier to maintain.