Gowhich

Durban's Blog

学习记录 - If

题目


实现一个utils If,它接受条件C,True返回类型T,以及False返回类型F。 C可以是True或False,而T和F可以是任何类型。

比如

1
2
type A = If<true, 'a', 'b'>  // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'

测试用例


1
2
3
4
5
6
7
8
9
import { Equal, Expect } from '@type-challenges/utils'

type cases = [
Expect<Equal<If<true, 'a', 'b'>, 'a'>>,
Expect<Equal<If<false, 'a', 2>, 2>>,
]

// @ts-expect-error
type error = If<null, 'a', 'b'>

答案


1
type If<C, T, F> = C extends true ? T : F

学习记录 - 实现内置的Exclude <T,U>

题目简介


实现内置的Exclude <T,U>

从T中排除可分配给U的那些类型


测试用例


1
2
3
4
5
6
7
import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils'

type cases = [
Expect<Equal<MyExclude<"a" | "b" | "c", "a">, Exclude<"a" | "b" | "c", "a">>>,
Expect<Equal<MyExclude<"a" | "b" | "c", "a" | "b">, Exclude<"a" | "b" | "c", "a" | "b">>>,
Expect<Equal<MyExclude<string | number | (() => void), Function>, Exclude<string | number | (() => void), Function>>>,
]

答案


1
type MyExclude<T, U> = T extends U ? never : T;

学习记录 - 获取元素长度 - 对于给定的元组,您需要创建一个通用的Length,选择元组的长度

题目简介


对于给定的元组,您需要创建一个通用的Length,选择元组的长度

例如

1
2
3
4
5
type tesla = ['tesla', 'model 3', 'model X', 'model Y']
type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT']

type teslaLength = Length<tesla> // expected 4
type spaceXLength = Length<spaceX> // expected 5

测试用例


1
2
3
4
5
6
7
8
9
import { Equal, Expect } from '@type-challenges/utils'

const tesla = ['tesla', 'model 3', 'model X', 'model Y'] as const
const spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'] as const

type cases = [
Expect<Equal<Length<typeof tesla>, 4>>,
Expect<Equal<Length<typeof spaceX>, 5>>,
]

答案


1
type Length<T extends any> = T extends ArrayLike<any> ? T["length"] : never

第一个元素 - 实现一个通用First<T>,它接受一个数组T并返回它的第一个元素的类型。学习记录如下


题目简介


实现一个通用First<T>,它接受一个数组T并返回它的第一个元素的类型。

例如

1
2
3
4
5
type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]

type head1 = First<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3

测试用例


1
2
3
4
5
6
7
8
import { Equal, Expect } from '@type-challenges/utils'

type cases = [
Expect<Equal<First<[3, 2, 1]>, 3>>,
Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,
Expect<Equal<First<[]>, never>>,
Expect<Equal<First<[undefined]>, undefined>>
]

答案


1
type First<T extends any[]> = T extends never[] ? never : T[0]

这里记录下使用Nest.js中,在控制器中如何添加所有请求方式的方法

第一种请求方式Get

1
2
3
4
5
6
7
8
9
@Get()
findAll() {
return 'This action will return all dogs';
}

@Get(':id')
findOne(@Param('id') id: string) {
return `This action will return one ${id} dog`;
}

第二种请求方式Post

1
2
3
4
@Post()
create(@Body() createDogDto: CreateDogDto) {
return `This action will add a dog`;
}

第三种请求方式Put

1
2
3
4
@Put(':id')
update(@Param('id') id: string, @Body() updateDogDto: UpdateDogDto) {
return `This action will update a dog`;
}

第四种请求方式Delete

1
2
3
4
@Delete(':id')
remove(@Param('id') id: string) {
return `This action will remote a dog`;
}

完整的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { CreateDogDto } from 'src/create-dog.dto';
import { UpdateDogDto } from 'src/update-dog.dto';

@Controller('dogs')
export class DogsController {
@Get()
findAll() {
return 'This action will return all dogs';
}

@Get(':id')
findOne(@Param('id') id: string) {
return `This action will return one ${id} dog`;
}

@Post()
create(@Body() createDogDto: CreateDogDto) {
return `This action will add a dog`;
}

@Put(':id')
update(@Param('id') id: string, @Body() updateDogDto: UpdateDogDto) {
return `This action will update a dog`;
}

@Delete(':id')
remove(@Param('id') id: string) {
return `This action will remote a dog`;
}
}

控制器payloads请求

如果通过Post请求来接收客户端的payloads参数

Nest.js通过使用@Body装饰器

首先创建一个DTO类,create-cats.dto.ts

1
2
3
4
5
export class CreateCatDto {
name: string;
age: number;
bread: string;
}

然后修改create方法

1
2
3
4
5
6
7
import { CreateCatDto } from 'src/create-cats.dto';

@Post()
async create(@Body() createCatDto: CreateCatDto) {
console.log(createCatDto);
return 'This action will create a new cat';
}

运行npm run start:dev

我们测试下

1
2
$ curl -d 'name=durban&age=12&bread=ddd' http://127.0.0.1:3000/cats
This action will create a new cat

可以看到console.log的输出结果如下

1
{ name: 'durban', age: '12', bread: 'ddd' }

异步机制

Nest.js也是支持现在javascript的异步机制的,async/await

同时每个async函数必须返回一个Promise

看个简单的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Controller, Get, HostParam } from '@nestjs/common';

@Controller('account')
export class AccountController {
@Get()
getInfo(@HostParam('account') account) {
return account;
}
@Get('all')
async findAll(): Promise<any[]> {
return [];
}
}

同时Nest.js还可以处理observable streams.

例子如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Controller, Get, HostParam } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Controller('account')
export class AccountController {
@Get()
getInfo(@HostParam('account') account) {
return account;
}

@Get('all')
findAll(): Observable<any[]> {
return of([]);
}
}

上面两个例子在访问的时候都会直接返回一个空数组

子域路由

@Controller装饰器提供了一个host选项可用,主要用来判断这个控制器在被访问的时候,限制具体的域名来访问

代码如下

1
2
3
4
5
6
7
8
@Controller('cats')
@Controller({ host: 'api.gowhich.com' })
export class CatsController {
@Get()
findAll(@Req() request: Request): string {
return 'This action will returns all cats';
}
}

再举个例子

1
2
3
4
5
6
7
8
@Controller('cats')
@Controller({ host: 'api.gowhich.com' })
export class CatsController {
@Get()
getInfo(@HostParam('account') account) {
return account;
}
}

开始记录前的说明

表名:users

表中字段名:id,name,age,ctime

创建索引

创建语句语法

db.COLLECTION_NAME.ensureIndex(keys[,options]) 用于3.0及以下版本

db.COLLECTION_NAME.createIndex(keys[,options])用于3.0及以上版本

keys:要建立索引的参数列表。

如:{KEY:1},其中key表示字段名,1表示升序排序,也可使用使用数字-1降序。
options:可选参数,表示建立索引的设置。

可选值如下:
background: Boolean - 在后台建立索引,以便建立索引时不阻止其他数据库活动。默认值为false。
unique: Boolean - 创建唯一索引。默认值 false。
name: String - 指定索引的名称。如果未指定,MongoDB会生成一个索引字段的名称和排序顺序串联。
partialFilterExpression: document - 如果指定,MongoDB只会给满足过滤表达式的记录建立索引.
sparse: Boolean - 对文档中不存在的字段数据不启用索引。默认值是 false。
expireAfterSeconds: integer - 指定索引的过期时间
storageEngine: document - 允许用户配置索引的存储引擎

第一个情况,创建单字段索引

1
db.users.createIndex({"name":1})

第二个情况,创建多字段索引

1
db.users.createIndex({"name":1,"age":1})

第三种情况,创建索引加可选项,这个情况建议多使用

1
db.users.createIndex({"name":1,"age":1}, {background: 1})

查看索引

记录几种常用的方法

  1. getIndexes()方法可以用来查看集合的所有索引,
  2. getIndexKeys()方法查看索引键。
  3. totalIndexSize()查看集合索引的总大小,
  4. getIndexSpecs()方法查看集合各索引的详细信息

删除索引

记录下常用方法

  1. dropIndex()方法用于删除指定的索引
  2. dropIndexes()方法用于删除全部的索引

重定向

Nest.js提供了一种方式可以重定向路由

方式可以通过使用装饰器@Redirect和res.redirect

这里记录下如何使用装饰器来重定向

1
2
3
4
5
6
7
8
9
@Get('items')
@Redirect('https://www.gowhich.com', 302)
getItems(@Query('version') version) {
if (version && version == 5) {
return {
url: 'https://www.gowhich.com/cats/items/v5',
};
}
}

当访问http://127.0.0.1:3000/cats/items,URI会被重定向到https://www.gowhich.com

当访问http://127.0.0.1:3000/cats/items?version=5,URI会被重定向到https://www.gowhich.com/cats/items/v5

获取路由参数

这里说的路由参数值的是,当访问cats/1这样的路由的时候,能否获取到1这个参数值

当然Nest.js也提供了一个非常好用的装饰器@Param

这个装饰器,我们可以使用两种方式来获取到参数

第一种

1
2
3
4
@Get(':id')
getOne(@Param() param): string {
return `This action return id #${param.id}`;
}

第二种

1
2
3
4
@Get(':name')
getName(@Param('name') name): string {
return `This action return name #${name}`;
}
0%