一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
中等
Merge
type Merge<F, S> = {
[P in keyof (F & S)]: P extends keyof S ? S[P]: (F & S)[P]
}
- 首先通过交叉类型操作符
&把F和S变为交叉类型,然后通过keyof就可以拿到键的联合类型了 - 由于
S需要覆盖F的key,所以在设置对象的值类型时,需要进行判断,优先使用S的值
CamelCase
type CamelCase<S extends string> =
S extends `${infer F}-${infer E}`
? `${F}${E extends Capitalize<E>
? `-${CamelCase<E>}`
: CamelCase<Capitalize<E>>}`
: S;
CamelCase是内置的工具类型,用来将字符串的首字母变为大写
通过模板字符串`${infer F}-${infer E}`就可以匹配到以-进行连接的字符串,例如:
foo-bar
foo--bar
bar----baz
然后针对泛型E进行处理就好了,根据是否以大写开头进行处理,所以就有了:
// E 要是非大写字母开头,就先用 Capitalize 进行转换,然后再继续调用 CamelCase,这样才能确保后面的字符串都能被处理到
`
${F}
${E extends Capitalize<E> ? `-${CamelCase<E>}` : CamelCase<Capitalize<E>>}
`
KebabCase
type KebabCase<S extends string> =
S extends `${infer F}${infer E}`
? E extends Uncapitalize<E>
? `${Uncapitalize<F>}${KebabCase<E>}`
: `${Uncapitalize<F>}-${KebabCase<E>}`
: S;
Uncapitalize 用于将字符串的首字母变为小写
- 因为要处理的字符没有特别的规律,所以就要对字符串进行遍历,使用条件就是
`${infer F}${infer E}`
泛型E为什么是使用Uncapitalize进行判断处理,而不是Capitalize呢?看下代码示例:
type T<S extends string> = S extends Capitalize<S> ? true : false;
// type A = true
type A = T<'-'>;
因为用Capitalize没法准确排除-、''、😎等字符,所以通过Uncapitalize才能准确判断出当前字符串是不是一个大写字母开头的字符串。
搞清楚后,拼接字符串就根据是不是大写开头来加个-就行了。
Diff
type Diff<O, O1> = Omit<O & O1, keyof (O | O1)>;
Omit<T, K>:从 T 对象类型中排除类型为 K 的键,返回新的对象类型
首先来看个例子:
// 结果:type a = "toString" | "valueOf"
type a = keyof (string | number);
使用联合类型运算符|将两个集合关联起来时,那么使用keyof取到的值是string和number都有的属性,这是取的并集。
所以使用keyof (O | O1)就能获取两个对象中都有的属性,那么剩下的属性就是我们想要的了,通过Omit就可以得到新的对象类型了。
答案参考自解答区,里面也有相关的解释