基础type最佳实践
type AppProps = {
/** string literals to specify exact string values, with a union type to join them together */
status: "waiting" | "success";
obj2: {}; // 对象最佳表示法
/** 明确字段的对象 */
obj3: {
id: string;
title: string;
};
/** array of objects! (common) */
objArr: {
id: string;
title: string;
}[];
dict2: Record<string, MyTypeHere>; // equivalent to dict1
/** function的最佳表示 */
onClick: () => void;
/** 有参数的function */
onChange: (id: number) => void;
/** 事件作为参数的最佳表示 */
onClick(event: React.MouseEvent<HTMLButtonElement>): void;
// react 节点的最佳表示
children: React.ReactNode; // best, accepts everything (see edge case below)
functionChildren: (name: string) => React.ReactNode; // recommended function as a child render prop type
style?: React.CSSProperties; // to pass through style props
onChange?: React.FormEventHandler<HTMLInputElement>; // form events! the generic parameter is the type of event.target
};
Types or Interfaces?
需要外部感知&merge采用 interface, 仅自己用的采用 type
Here’s a helpful rule of thumb:
- always use
interface
for public API’s definition when authoring a library or 3rd party ambient type definitions, as this allows a consumer to extend them via declaration merging if some definitions are missing. - consider using
type
for your React Component Props and State, for consistency and because it is more constrained. | Aspect | Type | Interface | | —- | —- | —- | | Can describe functions | ✅ | ✅ | | Can describe constructors | ✅ | ✅ | | Can describe tuples | ✅ | ✅ | | Interfaces can extend it | ⚠️ | ✅ | | Classes can extend it | 🚫 | ✅ | | Classes can implement it (implements
) | ⚠️ | ✅ | | Can intersect another one of its kind | ✅ | ⚠️ | | Can create a union with another one of its kind | ✅ | 🚫 | | Can be used to create mapped types | ✅ | 🚫 | | Can be mapped over with mapped types | ✅ | ✅ | | Expands in error messages and logs | ✅ | 🚫 | | Can be augmented | 🚫 | ✅ | | Can be recursive | ⚠️ | ✅ |