对于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)