您的位置:首页 > Web前端 > JavaScript

泛型 typescript_TypeScript泛型如何帮助您减少编写代码

2020-08-20 12:10 609 查看

泛型 typescript

When developers discuss Typescript, one of their main complaints is that you have to write more code to achieve the same result. While I agree with that, I think Typescript Generics can reduce the code you need to write to a great extent.

当开发人员讨论Typescript时,他们的主要抱怨之一是您必须编写更多代码才能获得相同的结果。 我同意这一点,但我认为Typescript泛型可以在很大程度上减少您需要编写的代码。

什么是TypeScript泛型? (What are TypeScript Generics?)

TS Generics can be used to bring abstraction into your TS interfaces. Using generics, you can pass an interface as a param to another interface.

TS泛型可用于将抽象带入您的TS接口。 使用泛型,可以将一个接口作为参数传递给另一个接口。

Here is an example of a standard API response for both a happy path and an error case.

这是一个关于愉快路径和错误情况的标准API响应的示例。

// successful response ✅
{
status: 'ok',
responseCode: 200,
data: {...}
}

// error response ❌
{
responseCode: 500,
errorMessage: "Something went wrong 😅";
}

Instead of writing an interface for every response and adding these keys, you can simply use Generics to create something like this:

无需为每个响应编写接口并添加这些键,您只需使用泛型来创建如下所示的内容:

interface ApiResponse<T>{
errorMessage?: string;
responseCode?: string;
data?: T;
}
interface UserData {
name: string;
email: string;
}
const response: ApiResponse<UserData> = {}

将泛型与函数链接 (Linking Generics with functions)

Let's assume we have a function that we use to make an API request to our backend.

假设我们有一个函数用于向后端发出API请求。

const getRequestTo = (endpoint: string) => {
return fetch(process.env.BE_HOST + endpoint).then(res => res.json())
}

const userResponse = getRequestTo('/user-data')

The type of

userResponse
would be
any
. We can have a better TypeScript implementation here.

userResponse
的类型为
any
。 我们可以在这里拥有更好的TypeScript实现。

const getRequestTo = async <R>(endpoint: string): Promise<ApiResponse<R>> => {
const request = await fetch(process.env.BE_HOST + endpoint);
const response = await request.json();
return response;
};

We can create a similar function for POST requests which also takes JSON as params of type

B
and the server will send back a JSON response of type
R
:

我们可以为POST请求创建一个类似的函数,该函数还将JSON作为类型

B
参数,服务器将发送回类型
R
的JSON响应:

const postRequestTo = async <B, R>(
endpoint: string,
body: B
): Promise<ApiResponse<R>> => {
const request = await fetch(process.env.BE_HOST + endpoint, {
method: "POST",
body: JSON.stringify(body),
});

const response = await request.json();

return response;
};

Similarly, there can be a PATCH request function as well, which handle‌s partial updates of any entity.

同样,也可以有一个PATCH请求功能,该功能处理任何实体的部分更新。

const patchRequestTo = async <B, R>(endpoint: string,body: Partial<B>): Promise<ApiResponse> => {
const request = await fetch(process.env.BE_HOST + endpoint, {
method: "PATCH",
body: JSON.stringify(body)
});
const response = await request.json();
return response;
};

Here is how to implement something like that:

这是实现此类内容的方法:

interface RequestBody {}
interface Response {}

const createPost = await postRequestTo<RequestBody, Response>('/post', postData);

const updatePost = await patchRequestTo<RequestBody, Response>('/post', {
title: "new name"
});

Let's pull it all together with a simple JavaScript class:

让我们将其与一个简单JavaScript类一起使用:

class ApiService<T> {
constructor(entitySlug: string) {
this.entitySlug = entitySlug;
}

private entitySlug: string;

getOne = async (id: string): Promise<APIResponse<T>> => {
const request = await fetch(process.env.BE_HOST + this.entitySlug + '/' + id);
const response = await request.json();
return response;
};

getList = async (): Promise<APIResponse<T[]>> => {
const request = await fetch(process.env.BE_HOST + this.entitySlug);
const response = await request.json();
return response;
};

create = async (body: Omit<T, 'id' | 'created' | 'updated'>): Promise<APIResponse<T>> => {
const request = await fetch(process.env.BE_HOST + this.entitySlug, {
method: 'POST',
body: JSON.stringify(body)
});

const response = await request.json();
return response;
};

update = async (
body: Omit<Partial<T>, 'id' | 'created' | 'updated'>
): Promise<APIResponse<T>> => {
const request = await fetch(process.env.BE_HOST + this.entitySlug + '/' + body.id, {
method: 'PATCH',
body: JSON.stringify(body)
});
const response = await request.json();
return response;
};

delete = async (id: string): Promise<void> => {
const request = await fetch(process.env.BE_HOST + this.entitySlug + '/' + id, {
method: 'DELETE'
});
const response = await request.json();
return response;
};
};

and you can then create an entity service like this:

然后您可以创建一个实体服务,如下所示:

export const postService = new ApiService<Post>('/post');

and it's all linked and ready for you.

一切都已链接并为您准备就绪。

Typescript has the potential to increase the developer experience tenfold if appropriately configured. These are some strategies to make that configuration process more comfortable. I hope this will help you use Typescript better in your current codebase.

如果配置正确,Typescript有可能将开发人员的体验提高十倍。 这些策略使配置过程更加舒适。 希望这可以帮助您在当前代码库中更好地使用Typescript。

翻译自: https://www.freecodecamp.org/news/make-typescript-easy-using-basic-ts-generics/

泛型 typescript

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: