typeScript & React

55 阅读2分钟

对于typeScript阅读了官方文档,对于一些基础的知识有了基本的了解。但是等到真正上手写react+typescript的时候,还是发现有很多地方不是很透彻,这边进行一些总结。

react结合typescript

export interface Props {
  name: string;
  enthusiasmLevel?: number;
}
// props-interface
function Hello({ name, enthusiasmLevel = 1 }: Props) {
  if (enthusiasmLevel <= 0) {
    throw new Error('You could be a little more enthusiastic. :D');
  }

  return (
    <div className="hello">
........
    </div>
  );
}
// 定义state结构
export interface StoreState {
    languageName: string;
    enthusiasmLevel: number;
}

// 定义action结构
export interface IncrementEnthusiasm {
    type: constants.INCREMENT_ENTHUSIASM;
}
export function incrementEnthusiasm(): IncrementEnthusiasm {
    return {
        type: constants.INCREMENT_ENTHUSIASM
    }
}

// reducer
export function enthusiasm(state: StoreState, action: EnthusiasmAction): StoreState {
}

// 创建容器
export interface Props {
  name: string;
  enthusiasmLevel?: number;
  onIncrement?: () => void;
  onDecrement?: () => void;
}
function Hello({ name, enthusiasmLevel = 1, onIncrement, onDecrement }: Props) {
}
export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>) {
}

const store = createStore<StoreState>(enthusiasm, {
  enthusiasmLevel: 1,
  languageName: 'TypeScript',
});

 

类型断言:

 // 1.尖括号写法
let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

// 2.as写法
let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

 

泛型:

泛型是重要的一个知识点,在常规中经常会使用

// 常规的用法是比如表示输入和输出类型的一致,可以使用泛型
// 其中T是任意值,一般熟悉使用T或U
function add<T>(params: T): T {
   return params
}

let output = identity<string>("myString"); 

// 在泛型约束中使用类型参数
// k extends keyof T, 则表示k是继承T的key属性
function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.

 

结合react+typescript

// 函数组件
const MyComponent: React.FC<Props> = ... 

// 类组件
class MyComponent extends React.Component<Props, State> { ...

// 高阶组件
const withState = <P extends WrappedComponentProps>(
  WrappedComponent: React.ComponentType<P>,
) => { ...

 

高级属性:

1.交叉类型

Person & Serializable & Loggable 表示同时是Person,Serializable,Loggable

function extend<T, U>(first: T, second: U): T & U {}

2.联合类型

number | string | boolean 表示可以是 number,string或boolean

3.类型保护与区分类型

let pet = getSmallPet();

if ((<Fish>pet).swim) {
    (<Fish>pet).swim();
}
else {
    (<Bird>pet).fly();
}

4.类型别名

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    }
    else {
        return n();
    }
}

5.索引类型

function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
  return names.map(n => o[n]);
}

interface Person {
    name: string;
    age: number;
}
let person: Person = {
    name: 'Jarid',
    age: 35
};
let strings: string[] = pluck(person, ['name']); // ok, string[]
let personProps: keyof Person; // 'name' | 'age'
let unknown = getProperty(person, 'unknown'); // error, 'unknown' is not in 'name' | 'age'

6.映射类型

// Partial 作用是将传入的属性变为可选项.
type PartialPerson = { [P in keyof Person]?: Person[P] }
type Partial<T> = { [P in keyof T]?: T[P] }

interface Foo {
  name: string;
  age: number;
}

type B = Partial<Foo>;

// 最多只能够定义 name, age 中的属性(可以不定义)
let b: B = {
  name: '1',
  age: 3,
};


//从 T 中取出 一系列 K 的属性
type Pick<T, K extends keyof T> = { [P in K]: T[P] };

 

 

 

 

react的实例使用:

type homeState = Pick<reducersMapType, 'home' | 'user'>
// 从 T 中取出 一系列 K 的属性

const Home: FC<homeState & typeof actions> = (props) => {
}

export default connect<homeState>(({ home, user }: reducersMapType) => ({ home, user }), actions)(Home)