This commit is contained in:
xugaoyi 2022-08-22 21:28:56 +08:00
parent 87370e0be1
commit 21f74b4ff9
1 changed files with 273 additions and 0 deletions

View File

@ -505,6 +505,87 @@ class SeniorTeacher extends Girls{
```typescript
// abstract关键字标注为抽象类没有具体实现不能用new实例化。子类继承该抽象类必须实现相应方法用于规范子类
abstract class Component<T1, T2> {
props: T1;
state: T2;
constructor(props: T1) {
this.props = props
}
// 用abstract标注为抽象类的方法不能有具体实现
abstract render(): string
}
// 规范类的props和state
interface Props {
val: number
}
interface State {
x: number
}
// 规范类内部的方法
interface Log {
getInfo(): string
}
interface Save {
save(): void
}
// <Props, State>通过泛型传入类型. implements 关键字使当前类必须要履行 Log,Storage 接口内定于的契约
class MyComponent extends Component<Props, State> implements Log, Save {
constructor(props: Props) {
super(props)
this.state = {
x: 1
}
}
render() {
// this.props.val
// this.state.x
return '<MyComponent>'
}
getInfo(): string {
return ''
}
save() {
}
}
const myComponent = new MyComponent({ val: 1 })
myComponent.render()
/**
* 类中的接口使用implements关键字
* 1. 如果一个类implements了一个接口那么就必须实现该接口中定义的契约
* 2. 多个接口使用逗号分隔
* 3. implements与extends可以同时存在
*/
/**
* TS中类和接口知识点
* 1. 抽象类在编译后会产生实体代码,接口不会
* 2. TS只支持继承即一个子类之能有一个父类
* 3. 接口不能有实现,抽象类可以有属性的实现,没有方法实现
*/
```
## 联合类型和类型保护
**联合类型** 指某个参数可以是多种类型。
@ -680,6 +761,198 @@ console.log(selectGirl2.getGirl(1))
## 类型保护
我们通常在 JavaScript 中通过判断来处理⼀些逻辑,在 TypeScript 中这种条件语句块还有另外⼀
个特性:根据判断逻辑的结果,缩⼩类型范围(有点类似断⾔),这种特性称为 类型保护 ,触发条
件:
- 逻辑条件语句块if、else、elseif
- 特定的⼀些关键字typeof、instanceof、in
#### typeof
```typescript
function fn(a: string|number) {
// error不能保证 a 就是字符串
a.substring(1);
if (typeof a === 'string') {
// ok
a.substring(1);
} else {
// ok
a.toFixed(1);
}
}
```
#### instanceof
```typescript
function fn(a: Date|Array<any>) {
if (a instanceof Array) {
a.push(1);
} else {
a.getFullYear();
}
}
```
#### in
```typescript
interface IA {
x: string;
y: string; }
interface IB {
a: string;
b: string; }
function fn(arg: IA | IB) {
if ('x' in arg) {
// ok
arg.x;
// error
arg.a;
} else {
// ok
arg.a;
// error
字⾯量类型保护
如果类型为字⾯量类型,那么还可以通过该字⾯量类型的字⾯值进⾏推断
⾃定义类型保护
有的时候,以上的⼀些⽅式并不能满⾜⼀些特殊情况,则可以⾃定义类型保护规则
arg.x;
}
}
```
#### 字面量类型保护
```typescript
interface IA {
type: 'IA';
x: string;
y: string;
}
interface IB {
type: 'IB';
a: string;
b: string;
}
function fn(arg: IA | IB) {
if (arg.type === 'IA') {
// ok
arg.x;
// error
arg.a;
} else {
// ok
arg.a;
// error
arg.x;
}
}
```
#### 自定义类型保护
```typescript
function canEach(data: any): data is Element[]|NodeList {
return data.forEach !== undefined;
}
function fn2(elements: Element[]|NodeList|Element) {
if ( canEach(elements) ) {
elements.forEach((el: Element)=>{
el.classList.add('box');
});
} else {
elements.classList.add('box');
}
}
```
`data is Element[]|NodeList` 是⼀种类型谓词,格式为: `xx is XX` ,返回这种类型的函数就可以
被 TypeScript 识别为类型保护
## 类型操作
#### typeof
获取数据的类型
```typescript
let str = 'kkk'
let t = typeof str // 使用typeof获取str的类型返回string给变量t 原生js的typeof使用
type myType = typeof str // 使用typeof获取str的类型返回string给类型myType TS的typeof使用
```
#### keyof
获取类型的所有`key`的集合
```typescript
// 使用示例1
interface Person{
name: string;
age: number;
}
type PersonKeys = keyof Person
// 等同: type PersonKeys = 'name' | 'age'; // 注意是key的集合不是值的集合
```
```typescript
// 使用示例2
let p1 = {
name: 'xx',
age: 28
}
// keyof typeof p1 的作用首先typeof将p1对象的类型取出keyof再将类型的key集合取出结果'name' | 'age'
function getPersonVal(k: keyof typeof p1){
return p1[k]
}
```
#### in
内部使用`for...in`对类型进行遍历
```typescript
interface Person{
name: string;
age: number;
}
type PersonKeys = keyof Person; // 'name' | 'age'
type NewPerson = {
[k in PersonKeys]: string
// 也可写成 [k in 'name' | 'age']: string
// 或 [k in keyof Person]: string
} // {name: string; age: string;}
```