typescript 完全指南
前言
这篇文章总结一下平时使用到 typescript 的问题,和一些高级用法
泛型 Genericity
理解泛型就两个字:传型, 如果和函数做类比,那范型就是函数的参数,可以传入任意类型的参数
最常见的Array
类型就是使用了泛型
在函数中使用
Array.prototype.delete = function <T>(index: number): T { |
在interface中使用
interface IBase<T> { |
interface 和 type
为什么要把interface
和 type
放在一起呢,因为他们两个都有相似指出,但是又有不同的地方
interface
interface
在TypeScript中用于定义对象的形状(shape),即对象应该有哪些属性以及它们的类型。接口是一种强大的方式来定义一个对象可以执行的操作和它应当具有的结构。接口通常用来定义对象的规范,以及类或对象必须实现的方法和属性。
|
在上面的例子中,任何实现了Person
接口的对象都必须有一个string类型的name属性、一个number类型的age属性,以及一个返回void的greet方法。
接口可以被继承和扩展,允许你创建新的接口,基于一个或多个现有的接口。
type
type是TypeScript中的类型别名,用于给一个类型起一个新的名字。它可以用来定义一个类型可以是什么。类型别名不仅仅可以用来定义对象的形状,还可以用来定义并集、交集、原始类型、元组、数组等。
type Greeting = "Hello" | "Hi" | "Hey"; |
在上面的例子中,Greeting是一个类型别名,它可以是三个特定的字符串中的一个;ID是一个可以是string或number的类型别名;User是一个对象的类型别名,有name和id属性。
type和interface的区别:
相同点:
- 都可以用来描述对象或函数的类型。
- 都可以在TypeScript中用来实现类型检查和智能感知。
不同点:
- interface可以被继承和扩展,而type不能。但type可以通过交集和并集操作创建新的类型。
- type可以用于定义其他类型的组合,比如联合类型、元组类型等,而interface通常不用于这些目的。
- type可以是任何有效的类型,包括基础类型、联合类型、交集类型、元组等,而interface主要用于定义对象的形状或行为。
使用场景
interface
适用场景:
- 当你需要定义一个对象的结构,尤其是当对象有可能被多个不同的类实现时。
- 当你需要通过继承来扩展现有的接口。
- 当你想要一个明确的合约来指定一个类必须实现哪些方法和属性时。
type
适用场景:
- 当你需要定义类型的并集或交集。
- 当你想要定义元组、映射类型或其他复杂的类型结构。
- 当你需要一个类型别名来简化复杂的类型表达式。
- 在实际应用中,
interface
和type
可以互换使用,选择使用哪一个很大程度上取决于个人或团队的偏好,以及具体的使用场景。有些团队可能更倾向于使用interface来定义对象的形状,因为它更加正式,表达了一种契约的概念;而另一些团队可能更偏好type的灵活性。在某些情况下,最佳实践可能是结合使用这两者的特点。
在实际应用中,interface
和type
可以互换使用,选择使用哪一个很大程度上取决于个人或团队的偏好,以及具体的使用场景。有些团队可能更倾向于使用interface来定义对象的形状,因为它更加正式,表达了一种契约的概念;而另一些团队可能更偏好type的灵活性。在某些情况下,最佳实践可能是结合使用这两者的特点。
implements
Implements 是一个用来描述类的关键词
interface BasePerson { |
交叉类型 , 联合类型
交叉类型 (并集) &
可以理解为,取两个类型的并集
语法 TypeA & TypeB
代码示例:
type Person1 = { |
联合类型 |
语法 typeA | typeB
|
内置类型
Typescript 除了内置的基本数据类型,还有一些内部封装好的的类型,这些类型可以帮助我们更好的编写代码
ReturnType
提取函数类型 T 的返回类型。
function f1(): number { return 0; } |
Partial
将类型 T 的所有属性变为可选的。
interface Todo { |
Required
将类型 T 的所有属性变为必选的。
interface Props { |
Readonly
interface Todo { |
Pick<T, K>
从类型 T 中挑选某些属性 K 来构造类型。
interface Todo { |
Record<K, T>
创建一个类型,其键是 K,值是 T。
type PageOptions = Record<'home' | 'about' | 'contact', { title: string }>; |
Exclude<T, U>
从类型 T 中排除可以赋给 U 的所有属性。
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c" |
Extract<T, U>
从类型 T 中提取可以赋给 U 的所有属性。
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a" |
Omit<T, K>
从类型 T 中剔除键 K。
interface Todo { |
NonNullable
从类型 T 中排除 null 和 undefined
type T0 = NonNullable<string | number | undefined>; // string | number |
Parameters
提取函数类型 T 的参数类型组成一个元组类型。
function f1(arg1: number, arg2: string): void {} |
InstanceType
获取构造函数类型的实例类型。
class C { |
Uppercase
将字符串类型中的每个字符转换为大写形式。
type T = Uppercase<'hello'>; // 'HELLO' |
Lowercase
将字符串类型中的每个字符转换为小写形式。
type T = Lowercase<'HELLO'>; // 'hello' |
Capitalize
将字符串类型中的第一个字符转换为大写形式。
type T = Capitalize<'hello'>; // 'Hello' |
Uncapitalize
将字符串类型中的第一个字符转换为小写形式。
type T = Uncapitalize<'Hello'>; // 'hello' |
高阶使用
typeof (typescript中的typeof)
语法:typeof <variable>
例子:typeof window
获取window的类型
ts中的typeof是获取目标对象的类型(可以动态的推断类型)
let SystemMap = { |
keyof ,用typeof获取对象的所有key的联合类型
语法:keyof <Type>
例子:keyof Object
获取Object的所有 key 的字符串的联合类型
如果配置keyof
使用,就可以得到 Linux,MacOS,Windows
这几种类型的字符串key值了
let SystemMap = { |
in 操作符
语法:[k in Keys]
例子:[k in 'Linux' | 'MacOS' | 'Windows' ]
在type中使用,k 表示被遍历的对象
注意:in操作符只在type中可以使用
**in操作符号约束声明对象的 key 和 value **
let SystemMap = { |
typeof 实现取 对象 key , value 类型的联合类型
let systemMap = { |
取interface的 value的联合类型
let systemMap = { |
tsconfig.json 配置速查表
{ |