基础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 typestyle?: React.CSSProperties; // to pass through style propsonChange?: 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
interfacefor 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
typefor 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 | ⚠️ | ✅ |
