Commit b1b2120d by zerozou

Add 2017.8.28 log:typescript and redux-ui

parent 95790e7b
# 2017/8/28
## Typescript
* 泛型
泛型既支持不同类型,虽然 ` any ` 也可以传入,但是会丢失类型信息。
* 类型变量 (e.g. `T` , `U`
只表示类型不表示值的变量
```typescript
function identity<T>(arg: T): T {
return arg
}
// 第一种传入类型参数
let output = identity<string>("hello, world")
// 第二种依靠编译器的类型推断
let output = identity("hello, world")
```
* 泛型接口(类)
```typescript
// 泛型放在调用签名上
interface GernericIdentity {
<T>(arg: T): T
}
function identity<T>(arg: T): T {
return arg
}
let myIdentity: GernericIdentity = identity
// 泛型放在接口上
interface GernericIdentity<T> {
(arg: T): T
}
let myIdentity: GernericIdentity<number> = identity
```
泛型类与泛型接口类似,泛型类指的是实例部分的类型,所以静态部分不能使用泛型类型
* 泛型约束
约束泛型需要包含某些属性,使用接口和 `extends` 关键字来约束
```typescript
interface Lengthwise {
length: number
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg
}
loggingIdentity(3) // error, number doesn't hava a .length propery
loggingIdentity({length:3, value: 3}) // success
```
* 装饰器(decorator)
装饰器是一种特殊类型的声明,它能被附加到类声明,方法, 访问符,属性或参数上。装饰器使用 `@expression` 这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。
* 装饰器组合
在一个声明上允许多个装饰器修饰,当多个装饰器修饰同一个声明时进行如下操作:
1. 由上至下依次对装饰器表达式求值
2. 求值的结果会被当作函数,由下至上依次调用
```typescript
@f
@g
x
// 求值方式类似复合函数,f(g(x))
```
* 装饰器求值
类中不同声明上的装饰器将按以下规定的顺序应用:
1. 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。
2. 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态成员。
3. 参数装饰器应用到构造函数。
4. 类装饰器应用到类。
* 类装饰器
类装饰器会在运行时当作函数被调用,类的构造函数作为唯一的参数。
```typescript
function seal(ctor: Function) {
Object.seal(ctor)
Object.seal(ctor.prototype)
}
@seal
class Greeter {
greeting: string
constructor(msg: string) {
this.greeting = msg
}
greet() {
return "Hello, " + this.greeting
}
}
```
* 方法装饰器
方法装饰器会在运行时当作函数被调用,传入以下参数:
1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象
2. 成员的名字
3. 成员的属性描述符
```typescript
function enumerable(value: boolean) {
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.enumerable = value
}
}
class Greeter {
greeting: string
constructor(msg: string) {
this.greeting = msg
}
@enumerable(false)
greet() {
return "Hello, " + this.greeting
}
}
```
* 访问器修饰符
访问器装饰器会在运行时当作函数被调用,传入以下参数:
1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象
2. 成员的名字
3. 成员的属性描述符
```typescript
function configurable(value: boolean) {
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value
}
}
class Point {
private _x: number
private _y: number
constructor(x: number, y: number) {
this._x = x
this._y = y
}
@configurable(false)
get x() {
return this._x
}
@configurable(false)
get y() {
return this._y
}
}
```
## Redux-ui
* 将redux-ui的reducer添加到自己的reducer中并设置为 `ui`
```javascript
import { reducer as uiReducer } from 'redux-ui'
combineReducer({
...myReducers,
ui: uiReducer
})
```
* 在每个父组件增加画UI的装饰器,并用 `state` 保存所有UI状态
```javascript
import ui from 'redux-ui'
@ui({
state: {
myValue: 'DefaultValue'
}
})
class MyComponent extends React.Component {
// ...
}
```
* 在每个子组件里使用基本的 `@ui()`装饰器,它能自动的让子组件读写父组件的UI状态。同样能给子组件定义自己的UI状态,如果子组件的与父组件有相同名字的UI状态,存在于子组件的读取子组件的状态,父组件用组件的状态,就类似于块级作用域。
* `@ui` 装饰器会给组件注入以下的 `props` :
1. `uiKey` : 从装饰器里传递的key(e.g. `@ui('some-decorator')`)
2. `ui` : 该组件的UI状态
3. `updateUI` : 一个函数接受其他的名值对或对象来更新该组件的UI状态
4. `resetUI` : 一个函数用来重置到该组件的默认状态
* `ui` 装饰器通过一个选项对象来配置
```javascript
@ui({
// 'key'选项用来决定存储UI状态的路径,若忽略,则会生成随机值
key: 'some-decorator',
// 'persist'选项,缺省值为false,如果设置为true,组件被卸载后仍能保持UI状态;如果设置为false,组件卸载后UI状态将被删除并在重新挂载的时候重新创建UI状态
persist: true,
// 组件UI状态
state: {
// ...
},
// customReducer: 可以通过dispatch action处理该组件作用域内UI状态
reducer: (state, action) => {
// state只相当于该组件的状态,不包括子组件的
// ...
},
// 传递给redux-react的@connect
mergeProps: () => ({}),
// 传递给redux-react的@connect
options: {},
})
```
* 不使用装饰器的写法
```javascript
import ui from 'redux-ui'
class MyComponent extends React.Component {
// ...
}
MyComponentWithUI = ui({key: '...', state: { ... }})(MyComponent)
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment