TypeScript中JSX的使用小结

 更新时间:2025年10月10日 09:59:00   作者:心随雨下  
本文主要介绍了TypeScript中JSX的使用小结, 使用JSX可以获得完整的类型检查和智能提示,从而提升开发效率和代码质量,感兴趣的可以了解一下

JSX 是一种 JavaScript 的语法扩展,允许在 JavaScript 代码中编写类似 HTML 的结构。在 TypeScript 中使用 JSX 可以获得完整的类型检查和智能提示。

1. 配置 TypeScript 支持 JSX

在 tsconfig.json 中配置 JSX 相关选项:

{
  "compilerOptions": {
    "jsx": "react-jsx",        // React 17+ 新的 JSX 转换
    // 或 "jsx": "react-jsxdev", // 开发模式
    // 或 "jsx": "preserve",     // 保留 JSX,由其他工具处理
    // 或 "jsx": "react",        // 传统的 React JSX 转换
    
    "jsxFactory": "React.createElement", // 自定义 JSX 工厂函数
    "jsxFragmentFactory": "React.Fragment" // 自定义 Fragment 工厂
  }
}

2. 基本 JSX 语法

2.1 元素类型

// 内置 HTML 元素
const divElement: JSX.Element = <div>Hello</div>;

// 自定义组件(PascalCase)
interface ButtonProps {
  onClick: () => void;
  children: React.ReactNode;
}

const Button: React.FC<ButtonProps> = ({ onClick, children }) => {
  return <button onClick={onClick}>{children}</button>;
};

// 使用组件
const App: React.FC = () => {
  return (
    <div>
      <Button onClick={() => console.log('Clicked!')}>
        Click me
      </Button>
    </div>
  );
};

2.2 属性类型

interface ImageProps {
  src: string;
  alt: string;
  width?: number;
  height?: number;
  className?: string;
  style?: React.CSSProperties;
}

const Image: React.FC<ImageProps> = (props) => {
  return <img {...props} />;
};

// 使用
<Image 
  src="image.jpg" 
  alt="Description" 
  width={100}
  style={{ border: '1px solid red' }}
/>

3. 类型系统

3.1 核心类型

// JSX 元素类型
const element: JSX.Element = <div />;

// 组件返回类型
const Component: React.FC = (): JSX.Element => {
  return <div>Hello</div>;
};

// 子元素类型
interface ContainerProps {
  children: React.ReactNode; // 最宽松的子元素类型
}

// 更具体的子元素类型
interface StrictContainerProps {
  children: React.ReactElement | React.ReactElement[];
}

// 没有子元素
interface NoChildrenProps {
  children?: never;
}

3.2 事件处理

interface FormProps {
  onSubmit: (data: FormData) => void;
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

const Form: React.FC<FormProps> = ({ onSubmit, onChange }) => {
  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    onSubmit(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        onChange={onChange}
        name="username"
      />
      <button type="submit">Submit</button>
    </form>
  );
};

4. 高级模式

4.1 条件渲染

interface UserInfoProps {
  user: { name: string; email: string } | null;
  isLoading: boolean;
}

const UserInfo: React.FC<UserInfoProps> = ({ user, isLoading }) => {
  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!user) {
    return <div>No user found</div>;
  }

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
};

4.2 列表渲染

interface TodoListProps {
  todos: Array<{
    id: number;
    text: string;
    completed: boolean;
  }>;
  onToggle: (id: number) => void;
}

const TodoList: React.FC<TodoListProps> = ({ todos, onToggle }) => {
  return (
    <ul>
      {todos.map(todo => (
        <li 
          key={todo.id}
          style={{ 
            textDecoration: todo.completed ? 'line-through' : 'none' 
          }}
          onClick={() => onToggle(todo.id)}
        >
          {todo.text}
        </li>
      ))}
    </ul>
  );
};

4.3 插槽模式

interface CardProps {
  title: string;
  header?: React.ReactNode;
  footer?: React.ReactNode;
  children: React.ReactNode;
}

const Card: React.FC<CardProps> = ({ title, header, footer, children }) => {
  return (
    <div className="card">
      {header && <div className="card-header">{header}</div>}
      <div className="card-body">
        <h3>{title}</h3>
        {children}
      </div>
      {footer && <div className="card-footer">{footer}</div>}
    </div>
  );
};

// 使用
<Card 
  title="My Card" 
  header={<button>Close</button>}
  footer={<span>Footer content</span>}
>
  Main content here
</Card>

5. 泛型组件

interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
  keyExtractor: (item: T) => string | number;
}

function List<T>({ items, renderItem, keyExtractor }: ListProps<T>): JSX.Element {
  return (
    <div>
      {items.map(item => (
        <div key={keyExtractor(item)}>
          {renderItem(item)}
        </div>
      ))}
    </div>
  );
}

// 使用泛型组件
interface User {
  id: number;
  name: string;
}

const users: User[] = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
];

<List
  items={users}
  keyExtractor={user => user.id}
  renderItem={user => <span>{user.name}</span>}
/>

6. 上下文(Context)与类型

interface Theme {
  mode: 'light' | 'dark';
  colors: {
    primary: string;
    background: string;
  };
}

// 创建带类型的 Context
const ThemeContext = React.createContext<Theme | undefined>(undefined);

interface ThemeProviderProps {
  theme: Theme;
  children: React.ReactNode;
}

const ThemeProvider: React.FC<ThemeProviderProps> = ({ theme, children }) => {
  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
};

// 自定义 Hook 用于消费 Context
const useTheme = (): Theme => {
  const theme = React.useContext(ThemeContext);
  if (!theme) {
    throw new Error('useTheme must be used within ThemeProvider');
  }
  return theme;
};

7. 高阶组件(HOC)

// 注入 props 的高阶组件
interface WithLoadingProps {
  isLoading: boolean;
}

function withLoading<P extends object>(
  Component: React.ComponentType<P>
): React.FC<P & WithLoadingProps> {
  return ({ isLoading, ...props }: P & WithLoadingProps) => {
    if (isLoading) {
      return <div>Loading...</div>;
    }
    return <Component {...props as P} />;
  };
}

// 使用
interface UserProfileProps {
  user: { name: string };
}

const UserProfile: React.FC<UserProfileProps> = ({ user }) => {
  return <div>{user.name}</div>;
};

const UserProfileWithLoading = withLoading(UserProfile);

8. 最佳实践

8.1 组件定义方式

// 1. Function Component with React.FC
const Component1: React.FC<Props> = (props) => { /* ... */ };

// 2. 直接定义函数(推荐,更灵活)
function Component2(props: Props): JSX.Element { /* ... */ }

// 3. 使用 PropsWithChildren(如果需要 children)
type Component3Props = React.PropsWithChildren<{
  title: string;
}>;

const Component3: React.FC<Component3Props> = ({ title, children }) => {
  return (
    <div>
      <h1>{title}</h1>
      {children}
    </div>
  );
};

8.2 事件处理类型

// 正确的类型定义
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
  event.preventDefault();
  // 处理点击
};

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  console.log(event.target.value);
};

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  // 处理提交
};

8.3 样式类型

// CSS Properties 类型安全
const styles: React.CSSProperties = {
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  backgroundColor: 'white', // 自动补全和类型检查
};

// 使用
<div style={styles}>Content</div>

这些是 TypeScript 中 JSX 的核心概念和最佳实践。通过类型系统的支持,可以在开发过程中获得更好的代码提示、错误检测和重构能力。

到此这篇关于TypeScript中JSX的使用小结的文章就介绍到这了,更多相关TypeScript JSX使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javascript验证上传图片大小[前台处理]

    Javascript验证上传图片大小[前台处理]

    在做上传图片的时候,如果不限制上传图片大小,后果非常的严重。解决这个问题有两种方式:后台处理、前台处理
    2014-07-07
  • JavaScript算法教程之sku(库存量单位)详解

    JavaScript算法教程之sku(库存量单位)详解

    这篇文章主要给大家介绍了JavaScript算法教程之sku(库存量单位)的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • JavaScript中读取和保存文件实例

    JavaScript中读取和保存文件实例

    这篇文章主要介绍了JavaScript中读取和保存文件实例,使用HTML5 File API实现,需要的朋友可以参考下
    2014-05-05
  • javascript实现确定和取消提示框效果

    javascript实现确定和取消提示框效果

    这篇文章主要介绍了javascript实现确定和取消提示框效果的方法以及示例代码分享,有需要的小伙伴可以参考下。
    2015-07-07
  • js 中获取制定的cook信息实现方法

    js 中获取制定的cook信息实现方法

    下面小编就为大家带来一篇js 中获取制定的cook信息实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • Threejs实现物理运动模拟

    Threejs实现物理运动模拟

    本文主要介绍了Threejs实现物理运动模拟,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • 解析从小程序开发者工具源码看原理实现

    解析从小程序开发者工具源码看原理实现

    小程序的架构设计与web技术还是有一定的差别,其吸取了web技术的一些优势,同时也摒弃web技术中体验等不好的地方。下面通过问题的形式来说说小程序架构中的一些设计点
    2021-06-06
  • 微信小程序学习总结(四)事件与冒泡实例分析

    微信小程序学习总结(四)事件与冒泡实例分析

    这篇文章主要介绍了微信小程序学习总结(四)事件与冒泡,结合实例形式分析了微信小程序事件、冒泡、数据获取相关机制、原理与操作注意事项,需要的朋友可以参考下
    2020-06-06
  • js实现透明度渐变效果的方法

    js实现透明度渐变效果的方法

    这篇文章主要介绍了js实现透明度渐变效果的方法,涉及javascript实现渐变效果的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • JavaScript优化if-else复杂判断问题的常用方案

    JavaScript优化if-else复杂判断问题的常用方案

    文章总结了八种常用代码优化模式,包括提前返回、卫语句、策略模式、查表法、多态、责任链模式、可选链和空值合并,并建议根据具体业务场景选择合适的优化方案,优先使用简单方案,保持一致性,考虑可读性,适度抽象,并进行充分测试,需要的朋友可以参考下
    2026-02-02

最新评论