⚠️⚠️⚠️ 文章来源与网络中知识总结与提炼,想要了解更多点击文末中链接自行了解
//function componenttype GreetProps = { age: number } & typeof defaultProps;const defaultProps = {age: 21,};const Greet = (props: GreetProps) => {/*...*/};Greet.defaultProps = defaultProps;
//class componenttype GreetProps = typeof Greet.defaultProps & {age: number,};class Greet extends React.Component<GreetProps> {static defaultProps = {age: 21,};/*...*/}// <Greet/>;
interface Square {kind: 'square';size: number;}interface Rectangle {kind: 'rectangle';width: number;height: number;}type Shape = Square | Rectangle;function area(s: Shape) {if (s.kind === 'square') {return s.size * s.size;} else {return s.width * s.height;}}
type Props1 = { foo: string };type Props2 = { bar: string };function MyComponent(props: Props1 | Props2) {if ('foo' in props) {// props.bar // 报错,不存在属性return <div>{props.foo}</div>;} else {// props.foo // 报错,不存在属性return <div>{props.bar}</div>;}}const UsageComponent: React.FC = () => (<div><MyComponent foo="foo" /><MyComponent bar="bar" />{/* <MyComponent foo="foo" bar="bar"/> // 无效 */}</div>);
interface Props<T> {items: T[];renderItem: (item: T) => React.ReactNode;}//魔法看这里const List=<T extends unknown>(props: Props<T>)=> {const { items, renderItem } = props;const [state, setState] = useState<T[]>([])return (<div>{items.map(renderItem)}<button onClick={() => setState(items)}>Clone</button>{JSON.stringify(state, null, 2)}</div>)}
现在我们回顾下函数组件:
...function List<T>(props:Props<T>){...}
bad
interface WrapperProps<T>{item:T;renderItem:(item:T)=>React.ReactNode;children:any; //👀}const Wrapper=<T extends {}>(props:WrapperProps<T>)=>{return(<div>{props.renderItem(props.item)}{props.children}</div>)}
good
// React.PropsWithChildreninterface WrapperProps<T>{item:T;renderItem:(item:T)=>React.ReactNode;}const Wrapper=<T extends {}>(props:React.PropsWithChildren<WrapperProps<T>>)=>{return(<div>{props.renderItem(props.item)}{props.children}</div>)}
/*** as const 可以让数组中每个值拥有自己的类型*/const useCtx=<A extends {}>(defaultValue:A)=>{type UpdateType=React.Dispatch<React.SetStateAction<typeof defaultValue>>;const defaultUpdate:UpdateType=()=>defaultUpdate;const ctx = React.createContext({state: defaultValue,update: defaultUpdate,});function Provider(props:React.PropsWithChildren<{}>){const [state,update]=React.useState(defaultValue);return <ctx.Provider value={{state,update}} {...props}/>}return [ctx,Provider] as const //👀👀}