blog: ts
This commit is contained in:
parent
87370e0be1
commit
21f74b4ff9
|
|
@ -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;}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue