Skip to content

Commit 9eb7436

Browse files
committed
开始使用typescript开发react组件
1 parent a61788d commit 9eb7436

File tree

3 files changed

+448
-0
lines changed

3 files changed

+448
-0
lines changed

react-pattern/readme.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,43 @@ const Content = () => (
100100

101101

102102

103+
#### 2.列表中所有Item依赖于接口全局变量
104+
比如有一个列表,列表中每一个组件的渲染都依赖于全局变量,而且这种全局变量的获取是依赖于接口的,此时可以通过如下方式解决:
105+
```js
106+
import React, { Component } from 'react';
107+
import EventProxy from "eventProxy";
108+
window.data = [];
109+
// js执行到这个位置的时候就请求,只会执行一次
110+
//全局的
111+
getVariables.then(data => {
112+
window.data = data;
113+
EventProxy.trigger('variableReceived', data);
114+
});
115+
116+
class Item extends Component {
117+
constructor(props) {
118+
super(props);
119+
this.state = {
120+
// 赋值
121+
data: window.data
122+
};
123+
if (window.data.length === 0) {
124+
// 若还没请求,则添加监听来等待数据
125+
EventProxy.on('variableReceived', data => {
126+
this.setState({
127+
data
128+
});
129+
});
130+
}
131+
}
132+
render() {
133+
return <div />;
134+
}
135+
}
136+
export default Item;
137+
```
138+
139+
103140

104141

105142
参考资料:

typescript/Generics.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
### 备注
2+
该部分只列举那些稍微难以理解的typescript的泛型相关内容,详细内容可以参考[TypeScript官网](http://www.typescriptlang.org/docs/handbook/generics.html)
3+
4+
### 1.泛型说明
5+
```js
6+
function identity(arg: any): any {
7+
return arg;
8+
}
9+
```
10+
上面的参数和返回值都是any类型,所以它本身就是一个泛型,但是可以通过更加优雅的方式来完成:
11+
```js
12+
// 1.第一个T表示为identity函数定义的一个类型变量,用于获取用户输入的类型,比如number
13+
// 2.第二个T表示该函数接受的参数
14+
// 3.第三个T表示函数的返回值
15+
function identity<T>(arg: T): T {
16+
return arg;
17+
}
18+
```
19+
调用泛型的方式有两种,第一种是传入所有的参数,包括参数类型:
20+
```js
21+
let output = identity<string>("myString");
22+
// type of output will be 'string'
23+
// 注意T是通过<>尖括号指定
24+
```
25+
第二种方式也是最常用的,依赖于编译器根据用户传入的值自动设置类型:
26+
```js
27+
let output = identity("myString"); // type of output will be 'string'
28+
```
29+
但是建议按照第一种方式指定下类型,在复杂情景下并不能保证编译器的自动识别准确性。
30+
31+
### 2.泛型变量
32+
对于上面的例子,直接访问arg.length将会抛出错误,因为arg不一定有length属性,所以可以使用泛型变量:
33+
```js
34+
function loggingIdentity<T>(arg: T[]): T[] {
35+
console.log(arg.length);
36+
// Array has a .length, so no more error
37+
return arg;
38+
}
39+
```
40+
当然也可以通过如下的方式书写:
41+
```js
42+
function loggingIdentity<T>(arg: Array<T>): Array<T> {
43+
console.log(arg.length);
44+
// Array has a .length, so no more error
45+
return arg;
46+
}
47+
```
48+
49+
### 3.泛型类型
50+
```js
51+
function identity<T>(arg: T): T {
52+
return arg;
53+
}
54+
let myIdentity: <T>(arg: T) => T = identity;
55+
```
56+
泛型函数与非泛型函数一样,先写泛型参数,和函数声明一样。我们也可以为泛型参数使用不同的名称:
57+
```js
58+
function identity<T>(arg: T): T {
59+
return arg;
60+
}
61+
let myIdentity: <U>(arg: U) => U = identity;
62+
```
63+
我们甚至可以在调用参数(call signature)中使用泛型:
64+
```js
65+
function identity<T>(arg: T): T {
66+
return arg;
67+
}
68+
let myIdentity: {<T>(arg: T): T} = identity;
69+
```
70+
下面写第一个泛型接口,我们将上例的对象常量移动到接口中:
71+
```js
72+
// 泛型接口
73+
interface GenericIdentityFn {
74+
<T>(arg: T): T;
75+
}
76+
function identity<T>(arg: T): T {
77+
return arg;
78+
}
79+
let myIdentity: GenericIdentityFn = identity;
80+
```
81+
相似的,可能想要将泛型参数作为接口的参数。这样类型参数将会对所有接口成员可见:
82+
```js
83+
interface GenericIdentityFn<T> {
84+
(arg: T): T;
85+
}
86+
function identity<T>(arg: T): T {
87+
return arg;
88+
}
89+
let myIdentity: GenericIdentityFn<number> = identity;
90+
```
91+
92+
### 4.泛型类
93+
泛型类和泛型接口类似,泛型类接受一个泛型的参数,该参数在类名括号内部。
94+
```js
95+
class GenericNumber<T> {
96+
zeroValue: T;
97+
add: (x: T, y: T) => T;
98+
}
99+
let myGenericNumber = new GenericNumber<number>();
100+
myGenericNumber.zeroValue = 0;
101+
//赋值
102+
myGenericNumber.add = function(x, y) { return x + y; };
103+
// 赋值函数
104+
```
105+
该例子使用的是number类型,其实也可以使用string类型,甚至更复杂的场景:
106+
```js
107+
let stringNumeric = new GenericNumber<string>();
108+
stringNumeric.zeroValue = "";
109+
stringNumeric.add = function(x, y) { return x + y; };
110+
console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));
111+
```
112+
注意:**泛型类的泛型表现在实例上而不是在静态成员上**,因此当使用类的时候,静态成员是不能使用泛型类型的。
113+
114+
### 5.泛型约束
115+
#### 5.1 普通约束
116+
上面length的例子,typescript告诉我们不能假设T有length属性,其实可以采用下面的方式来解决:
117+
```js
118+
interface Lengthwise {
119+
length: number;
120+
}
121+
function loggingIdentity<T extends Lengthwise>(arg: T): T {
122+
console.log(arg.length);
123+
// Now we know it has a .length property, so no more error
124+
return arg;
125+
}
126+
```
127+
现在泛型函数已经被约束了,它不再对所有的类型起作用:
128+
```js
129+
loggingIdentity(3); // Error, number doesn't have a .length property
130+
```
131+
所有需要传入的参数有length参数:
132+
```js
133+
loggingIdentity({length: 10, value: 3});
134+
```
135+
136+
#### 5.2 泛型约束使用Type参数
137+
你可以声明一个类型参数,该参数受另外一个参数的约束:
138+
```js
139+
function getProperty<T, K extends keyof T>(obj: T, key: K) {
140+
return obj[key];
141+
}
142+
let x = { a: 1, b: 2, c: 3, d: 4 };
143+
getProperty(x, "a"); // okay
144+
getProperty(x, "m");
145+
// error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
146+
```
147+
148+
#### 5.3 泛型中使用class类型
149+
当使用泛型去创建工厂函数,此时需要依赖于构造函数推断类型:
150+
```js
151+
function create<T>(c: {new(): T; }): T {
152+
return new c();
153+
}
154+
```
155+
下面是稍微复杂的使用prototype属性去推断和约束构造函数以及实例关系的例子:
156+
```js
157+
class BeeKeeper {
158+
hasMask: boolean;
159+
}
160+
class ZooKeeper {
161+
nametag: string;
162+
}
163+
class Animal {
164+
numLegs: number;
165+
}
166+
class Bee extends Animal {
167+
keeper: BeeKeeper;
168+
}
169+
class Lion extends Animal {
170+
keeper: ZooKeeper;
171+
}
172+
// c: A的意思是,c的类型是A,但这个函数的目的不是要求c的类型是A,而是要求c就是A。
173+
// createInstance函数的参数是一个Class,返回值是这个Class的实例。
174+
// https://segmentfault.com/q/1010000014470603
175+
function createInstance<A extends Animal>(c: new () => A): A {
176+
return new c();
177+
}
178+
createInstance(Lion).keeper.nametag; // typechecks!
179+
createInstance(Bee).keeper.hasMask; // typechecks!
180+
```
181+
更多内容请[查看官网](http://www.typescriptlang.org/docs/handbook/generics.html)

0 commit comments

Comments
 (0)