Japanese Full-Text Search in SQLite

Posted on Thursday, 19 May 2022Suggest An Edit

我们来封装一个泛型,它接收一个对象的类型,返回所有可能属性值的类型。

type ValueOf<O> = O[keyof O];

声明一个对象,测试一下:

const obj = {
	a: 1,
	b: 2,
	c: 3,
} as const;
type Obj = typeof obj;
type ObjValues = ValueOf<Obj>;

获取函数的返回值类型

我们现在有一个简单的函数fn

const fn = (a: string, b: number) => {
	return `${a}-${b}`;
};

现在想获取到fn函数的返回值类型,用作其他操作。我们可以使用Typescript内置的工具泛型Returntype

type FnReturnType = ReturnType<typeof fn>;

获取函数的参数类型

如果我又想知道fn函数的第一个参数a的类型,可以使用Parameters

type FnParametersType = Parameters<typeof fn>;
type AType = FnParametersType[0];

上面FnParametersType存的是一个Tuple,也就是一个元组,我们通过取第一个元素来获取参数a的类型。

获取Promise包裹的类型

我们有一个async函数,它返回一个对象,最终会被Promise包裹。

const getUser = async () => {
	return {
		id: 1,
		name: "zhaomeicheng",
		gender: "male",
	};
};

我们想得到最终return的对象的类型,但是有讨厌的Promise泛型存在,类似于Promise<{ id: number, name: string, gender: string}> 这时可以使用Awaited

type User = Awaited<ReturnType<typeof getUser>>;

这里的Awaited就好像我们JavaScript里await promise,最终会把promise的成功值给到等号的右边一样

获取对象的属性组成的联合类型

假设我现在有一个对象如下:

const obj = {
	prop1: {},
	prop2: {},
	prop3: {},
};

我希望可以得到prop1 | prop2 | prop3,这里面就要用到keyof了!

type Keys = keyof typeof obj;

函数throw an error,怎么就never了。

function alwaysError(): never {
	throw new Error("here is an error");
}

never是Typescript类型系统里的Bottom Type,中文翻译过来就是“从不”的意思,但是为什么上面代码的返回类型是never而不是void呢? 我个人理解,never可以理解标注事情不会到达,因为这个函数抛出错误导致函数永远不会有返回值,所以使用never

关于never的用户,就是用来做兜底检查的,我们有一个函数,参数可能为string或者number,但是如果有一天,别人扩展出了boolean,却没有针对boolean情况进行处理,这不是我们想要的,利用never可以进行检查报错。

const fn = (arg: string | number) => {
	if (typeof arg === "string") {
	} else if (typeof arg === "number") {
	} else {
		const neverValue: never = arg;
	}
};

如果后续别人给arg加了别的类型,但是几乎任何类型的值赋值给never,都会报错。这样就达到了代码可维护的目的。

TSconfig中有一个配置项叫做StrictNullChecks,默认是关闭的。 在这种上下文中,undefined和null是几乎任何类型的子类型,也就是说我可以把undefined和null赋值给任何变量:

let str: string;
let num: number;

str = null;
str = undefined;

num = null;
num = undefined;

但是这样很容易存在问题,假设我有一个函数,接收person对象,读取person的name属性,然后输出:

const sayName = (person: { name: string }) => {
	console.log(person.name);
};
sayName(null);
sayName(undefined);

上面代码TS并不会提示报错,然而在runtime执行时,尝试读取null/undefined的属性,会导致程序崩溃。 但是一旦开启了strictNullchecks以后,undefined和null不再属于任何一个集合,也意味着再讲null和undefined赋值给任何变量,TS都不再允许。


sortByKey (泛型练习)

function sortByKey<T>(data: T[], key: keyof T) {
	data.sort((pre, next) => {
		if (pre[key] > next[key]) return 1;
		if (pre[key] < next[key]) return -1;
		return 0;
	});
}

keyof能够获取到一个interface的所有key组成的联合类型,很好用。

映射类型 mapped type

type MyPick<T, U extends keyof T> {
  [K in U]: T[K]
}

interface Example {
  a: string;
  b: number;
  c: boolean;
}

type Picked = MyPick<Example, 'a' | 'b'>