<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Clane&#x27;s Notes</title>
      <link>https://clanedev.github.io/blog/</link>
      <description>An area where to store my ideas and notes.</description>
      <generator>Zola</generator>
      <language>zh</language>
      <atom:link href="https://clanedev.github.io/blog/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Thu, 13 Nov 2025 00:00:00 +0000</lastBuildDate>
      <item>
          <title>React+TypeScript 组件类型注解的两种核心写法</title>
          <pubDate>Thu, 13 Nov 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://clanedev.github.io/blog/projects/test/</link>
          <guid>https://clanedev.github.io/blog/projects/test/</guid>
          <description xml:base="https://clanedev.github.io/blog/projects/test/">&lt;p&gt;对于 React 初学者来说，TypeScript 类型注解常常是入门难点——尤其是组件 props 的类型定义，既想让 IDE 给出清晰提示（必选&#x2F;可选、类型、参数名），又不想被复杂的类型语法绕晕。&lt;&#x2F;p&gt;
&lt;p&gt;本文将总结两种最实用的 React 组件类型注解写法，帮你快速上手并做出合适选择。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yi-he-xin-qian-ti-wei-shen-me-xu-yao-zu-jian-lei-xing-zhu-jie&quot;&gt;一、核心前提：为什么需要组件类型注解？&lt;&#x2F;h2&gt;
&lt;p&gt;在写 React 组件时，类型注解的核心价值的是：&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IDE 智能提示&lt;&#x2F;strong&gt;：父组件使用时，自动显示 props 名称、必选&#x2F;可选标记、类型说明；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;提前报错&lt;&#x2F;strong&gt;：漏传必选 props、传错类型时，TypeScript 直接标红，避免运行时 bug；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;代码可读性&lt;&#x2F;strong&gt;：他人（或未来的你）看代码时，能快速知道组件需要什么参数。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;而我们要讲的两种写法，都能实现这些价值——只是风格和适用场景不同。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;er-xie-fa-yi-function-guan-jian-ci-dan-du-props-jie-kou&quot;&gt;二、写法一：Function 关键词 + 单独 Props 接口&lt;&#x2F;h2&gt;
&lt;p&gt;这是最贴合直觉的写法，尤其适合刚接触 React+TS 的同学，核心是“先定义 props 类型，再给组件函数标注类型”。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-ji-chu-xie-fa-wan-zheng-shi-li&quot;&gt;1. 基础写法（完整示例）&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;tsx&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 1. 导入 React（可选，若用 JSX.Element 需导入）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; React&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;react&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 2. 定义语义化 Props 接口（组件名 + Props 命名规范）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; GreetingCardProps&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; 必选属性：无 ? 符号，类型明确&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; 可选属性：带 ? 符号，可配合默认值&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;?:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; 复杂类型：回调函数（参数类型+返回值类型）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;  onSend&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;?:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 3. 组件定义：function 关键词 + 参数解构 + 类型标注&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; GreetingCard&lt;&#x2F;span&gt;&lt;span&gt;({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  username&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;欢迎使用 React+TS！&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; 可选属性设置默认值&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  onSend&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; GreetingCardProps&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; JSX&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;Element&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; 显式标注返回值类型&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; handleClick&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    &#x2F;&#x2F; 可选链语法：避免 onSend 为 undefined 时报错&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;    onSend&lt;&#x2F;span&gt;&lt;span&gt;?.(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;`${&lt;&#x2F;span&gt;&lt;span&gt;username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;}说：${&lt;&#x2F;span&gt;&lt;span&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;}`&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; className&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;greeting-card&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;你好，{username}！&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;{message}&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; onClick&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{handleClick}&amp;gt;发送消息&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 4. 导出组件（分开导出，提升可读性和扩展性）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;export default&lt;&#x2F;span&gt;&lt;span&gt; GreetingCard;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;2-he-xin-yao-dian-chu-xue-zhe-bi-kan&quot;&gt;2. 核心要点（初学者必看）&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Props 接口命名&lt;&#x2F;strong&gt;：必须遵循 &lt;code&gt;[组件名]Props&lt;&#x2F;code&gt;（如 &lt;code&gt;GreetingCardProps&lt;&#x2F;code&gt;），语义化且易关联；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;解构位置&lt;&#x2F;strong&gt;：在函数参数中直接解构 props，父组件使用时能看到具体参数提示（而非模糊的 &lt;code&gt;props&lt;&#x2F;code&gt; 变量）；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;返回值类型&lt;&#x2F;strong&gt;：用 &lt;code&gt;JSX.Element&lt;&#x2F;code&gt; 更直观（与 JSX 语法对应），和 &lt;code&gt;React.ReactElement&lt;&#x2F;code&gt; 本质等价；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;export 写法&lt;&#x2F;strong&gt;：分开导出（先定义后导出），避免一行代码拥挤，后续添加静态属性&#x2F;扩展更方便。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;3-fu-zu-jian-shi-yong-xiao-guo&quot;&gt;3. 父组件使用效果&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;tsx&quot;&gt;&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2B3036;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; GreetingCard&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;.&#x2F;GreetingCard&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2B3036;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; JSX&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;Element&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2B3036;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2B3036;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;      {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;* 输入 &amp;lt;GreetingCard 后，IDE 自动提示：&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        - username（必选）: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        - message（可选）: string | undefined&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2B3036;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        - onSend（可选）: (content: string) =&amp;gt; void&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;GreetingCard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;小明&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;一起学习 TypeScript 吧！&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;        onSend&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; console.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(content)}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;      &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;  );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #444D56;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;san-xie-fa-er-const-jian-tou-han-shu-react-fc-han-shu-shi-feng-ge-shou-xuan&quot;&gt;三、写法二：Const 箭头函数 + React.FC（函数式风格首选）&lt;&#x2F;h2&gt;
&lt;p&gt;这种写法是“const 变量 + 箭头函数 + React.FC 泛型”，核心是用 React 内置的 &lt;code&gt;React.FC&lt;&#x2F;code&gt;（FunctionComponent）类型模板，简化类型标注。&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-ji-chu-xie-fa-wan-zheng-shi-li-1&quot;&gt;1. 基础写法（完整示例）&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;tsx&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; React&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;react&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 1. 定义 Props 接口（无需手动加 children！）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; GreetingCardProps&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;?:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;  onSend&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;?:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; 2. 组件定义：React.FC&amp;lt;Props&amp;gt; 标注变量类型&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; GreetingCard&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; React&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;FC&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;GreetingCardProps&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  username,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;欢迎使用 React+TS！&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  onSend,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  children,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; 自动获得 children 属性，无需在 Props 接口定义&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;})&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; handleClick&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;    onSend&lt;&#x2F;span&gt;&lt;span&gt;?.(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;`${&lt;&#x2F;span&gt;&lt;span&gt;username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;}说：${&lt;&#x2F;span&gt;&lt;span&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;}`&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; className&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;greeting-card&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;你好，{username}！&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;{message}&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      {children} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;* 直接使用 children，无需额外配置 *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; onClick&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{handleClick}&amp;gt;发送消息&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;export default&lt;&#x2F;span&gt;&lt;span&gt; GreetingCard;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;2-he-xin-yao-dian-gao-dong-react-fc-de-ben-zhi&quot;&gt;2. 核心要点（搞懂 React.FC 的本质）&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;React.FC 是什么？&lt;&#x2F;strong&gt;：它是 React 内置的&lt;strong&gt;泛型类型模板&lt;&#x2F;strong&gt;，本质是给变量标注“这是一个 React 函数组件”，语法简化为 &lt;code&gt;React.FC&amp;lt;Props接口&amp;gt;&lt;&#x2F;code&gt;；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;自动包含的特性&lt;&#x2F;strong&gt;：
&lt;ol&gt;
&lt;li&gt;内置 &lt;code&gt;children?: React.ReactNode&lt;&#x2F;code&gt; 属性，无需在 Props 接口手动定义；&lt;&#x2F;li&gt;
&lt;li&gt;自动约束返回值类型为 &lt;code&gt;JSX.Element&lt;&#x2F;code&gt;，不用额外写返回值标注；&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;变量标注的意义&lt;&#x2F;strong&gt;：&lt;code&gt;const GreetingCard: React.FC&amp;lt;GreetingCardProps&amp;gt;&lt;&#x2F;code&gt; 是给变量 &lt;code&gt;GreetingCard&lt;&#x2F;code&gt; 贴“组件标签”，告诉 TypeScript 这个变量对应的箭头函数是 React 组件，需遵循 Props 接口规范。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;3-fu-zu-jian-shi-yong-xiao-guo-1&quot;&gt;3. 父组件使用效果&lt;&#x2F;h3&gt;
&lt;p&gt;和写法一完全一致——父组件使用时，IDE 同样会显示完整的 props 提示（必选&#x2F;可选、类型、名称），漏传必选 props 会标红报错。&lt;&#x2F;p&gt;
&lt;h2 id=&quot;si-liang-chong-xie-fa-he-xin-dui-bi-chu-xue-zhe-zen-me-xuan&quot;&gt;四、两种写法核心对比（初学者怎么选？）&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;对比维度&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;写法一（Function + 单独 Props）&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;写法二（Const 箭头 + React.FC）&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;可读性&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;高，符合传统函数认知，新手易理解&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;简洁，但需理解 React.FC 泛型，略抽象&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;children 支持&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;需手动在 Props 接口添加 &lt;code&gt;children?: React.ReactNode&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;自动内置，无需手动定义&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;返回值类型&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;需显式标注 &lt;code&gt;: JSX.Element&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;自动推导，无需额外标注&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;静态属性扩展&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;直接挂载（&lt;code&gt;GreetingCard.static = ...&lt;&#x2F;code&gt;）&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;需先赋值给变量，再挂载（多一行代码）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;useCallback 兼容&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;完全兼容，直接包裹 function 函数&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;兼容，包裹箭头函数（写法更统一）&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;学习成本&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;低，只需掌握接口和函数类型标注&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;中，需额外理解 React.FC 泛型概念&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;xuan-ze-jian-yi&quot;&gt;选择建议：&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;优先选写法一&lt;&#x2F;strong&gt;：如果你是初学者，觉得 &lt;code&gt;function&lt;&#x2F;code&gt; 更易理解，或组件很少用 &lt;code&gt;children&lt;&#x2F;code&gt;，选这种——直观、少踩坑，核心功能完全满足；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;选写法二的场景&lt;&#x2F;strong&gt;：如果团队用函数式编程风格（箭头函数为主），或组件经常需要 &lt;code&gt;children&lt;&#x2F;code&gt; 属性，选这种——能省掉 &lt;code&gt;children&lt;&#x2F;code&gt; 定义，写法更简洁；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;核心原则&lt;&#x2F;strong&gt;：两种写法在功能上无优劣，&lt;strong&gt;优先选择你能看懂、写起来顺手的&lt;&#x2F;strong&gt;，项目内保持风格一致即可。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;wu-chu-xue-zhe-bi-keng-zhi-nan&quot;&gt;五、初学者避坑指南&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不要混用两种写法&lt;&#x2F;strong&gt;：比如 &lt;code&gt;function GreetingCard: React.FC&amp;lt;Props&amp;gt; () {}&lt;&#x2F;code&gt; 是错误的，React.FC 只能标注变量（箭头函数&#x2F;函数表达式），不能标注 function 声明；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Props 接口不要省略&lt;&#x2F;strong&gt;：即使组件只有一个 props，也建议定义单独接口（如 &lt;code&gt;interface ButtonProps { text: string }&lt;&#x2F;code&gt;），比直接写 &lt;code&gt;(props: { text: string })&lt;&#x2F;code&gt; 更易维护；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;可选属性必加默认值&lt;&#x2F;strong&gt;：可选属性（带 &lt;code&gt;?&lt;&#x2F;code&gt;）建议设置默认值（如 &lt;code&gt;message = &#x27;默认文案&#x27;&lt;&#x2F;code&gt;），避免组件内频繁判断 &lt;code&gt;undefined&lt;&#x2F;code&gt;；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;export 写法推荐&lt;&#x2F;strong&gt;：无论哪种写法，都建议“先定义组件，后导出”（分开写），避免一行代码过长，后续扩展更方便。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;zong-jie&quot;&gt;总结&lt;&#x2F;h2&gt;
&lt;p&gt;React+TypeScript 组件类型注解的核心是“明确 props 类型”，两种写法都能实现 IDE 提示、类型校验和可读性提升：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;初学者优先选 &lt;strong&gt;Function 关键词 + 单独 Props 接口&lt;&#x2F;strong&gt;，直观易理解，学习成本低；&lt;&#x2F;li&gt;
&lt;li&gt;熟悉泛型后可尝试 &lt;strong&gt;Const 箭头函数 + React.FC&lt;&#x2F;strong&gt;，适合函数式风格和频繁使用 &lt;code&gt;children&lt;&#x2F;code&gt; 的场景。&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;不用纠结“哪种更好”，掌握一种写法并熟练运用，再根据项目需求或团队规范切换即可——核心是让 TypeScript 帮你减少 bug，让代码更清晰。&lt;&#x2F;p&gt;
&lt;p&gt;如果需要进一步学习，建议先熟练掌握接口定义和函数类型标注，再深入理解 React.FC 等 React 内置类型工具，逐步提升 TypeScript 运用能力～&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;解构赋值已经在当前作用域 “声明” 了变量（比如&lt;code&gt;bookmarks&lt;&#x2F;code&gt;），后续再用&lt;code&gt;const&#x2F;let&#x2F;var&lt;&#x2F;code&gt;声明同名变量，就违反了 “同一作用域不能重复声明” 的规则&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jie-jue-ban-fa&quot;&gt;解决办法&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;1-jie-gou-shi-zhi-jie-zhong-ming-ming-tui-jian&quot;&gt;1. 解构时直接 “重命名”（推荐）&lt;&#x2F;h4&gt;
&lt;p&gt;直接在解构时给 props 里的变量起个 “别名”，避免冲突 —— 这是 JS 解构语法支持的原生功能&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; BookmarkList&lt;&#x2F;span&gt;&lt;span&gt;({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; bookmarks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFAB70;&quot;&gt; propsBookmarks&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; Props&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;2-bu-zhong-fu-ming-ming&quot;&gt;2. 不重复命名&lt;&#x2F;h4&gt;
&lt;p&gt;换个语义化的变量名，props 里的&lt;code&gt;bookmarks&lt;&#x2F;code&gt;是 “原始数据”，后续处理后的可以叫&lt;code&gt;filteredBookmarks&lt;&#x2F;code&gt;（过滤后）、&lt;code&gt;sortedBookmarks&lt;&#x2F;code&gt;（排序后），既避免冲突，代码可读性也更高。&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>读《Tiny Habits》的一个启发</title>
          <pubDate>Tue, 11 Nov 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://clanedev.github.io/blog/books/tiny-habits/</link>
          <guid>https://clanedev.github.io/blog/books/tiny-habits/</guid>
          <description xml:base="https://clanedev.github.io/blog/books/tiny-habits/">&lt;p&gt;当一个行为没有发生，我们该从哪儿找原因？&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;不够努力？&lt;&#x2F;li&gt;
&lt;li&gt;态度有问题？&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;</description>
      </item>
      <item>
          <title>《张忠谋自传 · 上》 什么是学习曲线？</title>
          <pubDate>Thu, 09 Oct 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://clanedev.github.io/blog/books/zhang-zhong-mou-zi-chuan/</link>
          <guid>https://clanedev.github.io/blog/books/zhang-zhong-mou-zi-chuan/</guid>
          <description xml:base="https://clanedev.github.io/blog/books/zhang-zhong-mou-zi-chuan/">&lt;p&gt;什么是学习曲线？&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;随着生产经验的积累，单位产品的成本会不断下降。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;张忠谋在德仪（Texas Instruments）时，韩德生（Henderson）提出这个理论，帮助他们理解&lt;strong&gt;制造效率与经验的关系&lt;&#x2F;strong&gt;。&lt;&#x2F;p&gt;
&lt;p&gt;张忠谋大力称赞这个理论，让我有些迷惑，做的越多，越熟练，这难道不是常识吗？&lt;&#x2F;p&gt;
&lt;p&gt;把“常识”&lt;strong&gt;量化成可以预测、可以决策的工具&lt;&#x2F;strong&gt;。 这就是它从“正确的废话”变成“战略武器”的地方。&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>有哪些初始成本极低、后果延迟且不可逆的行为？</title>
          <pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://clanedev.github.io/blog/posts/you-na-xie-chu-shi-cheng-ben-ji-di-hou-guo-yan-chi-qie-bu-ke-ni-de-xing-wei/</link>
          <guid>https://clanedev.github.io/blog/posts/you-na-xie-chu-shi-cheng-ben-ji-di-hou-guo-yan-chi-qie-bu-ke-ni-de-xing-wei/</guid>
          <description xml:base="https://clanedev.github.io/blog/posts/you-na-xie-chu-shi-cheng-ben-ji-di-hou-guo-yan-chi-qie-bu-ke-ni-de-xing-wei/">&lt;p&gt;利用 “行为门槛低 + 风险感知弱” 的心理反差，引导用户做出看似轻松、实则影响深远的决策。&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;压缩 “初始决策成本”&lt;&#x2F;strong&gt;：让行为 “触手可及”，降低用户的思考和行动门槛；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;延迟 “负面后果感知”&lt;&#x2F;strong&gt;：让风险在遥远的未来显现，避免即时压力干扰决策；&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;锁定 “后果不可逆性”&lt;&#x2F;strong&gt;：一旦行为发生，损失或影响无法轻易撤销，从而形成 “决策 - 后果” 的强绑定。&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;“剪标不退换” 的服装销售&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;商家把衣服上的纸质标签换成硬塑料的，还把标签位置从不影响试穿的拉链处，挪到了会直接蹭到皮肤的脖颈处 —— 故意让标签磨得人不舒服，好让用户忍不住剪掉标签。而衣服一旦剪了标，通常就不能退换了。&lt;&#x2F;p&gt;
&lt;p&gt;其心理学本质是：&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用即时痛苦掩盖长期风险&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;塑料标签的摩擦感是&lt;strong&gt;即时且明确的负面刺激&lt;&#x2F;strong&gt;，而「剪标导致无法退换」的后果是&lt;strong&gt;延迟且模糊的潜在风险&lt;&#x2F;strong&gt;。根据&lt;strong&gt;即时满足偏差&lt;&#x2F;strong&gt;，用户会优先处理眼前的不适，而非考虑未来可能的退货需求。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用行为惯性切断退路&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;商家将标签位置从拉链处（不影响试穿）移至脖颈处，实际上创造了一个 &lt;strong&gt;「忍受摩擦」或「剪标」的强制选择场景&lt;&#x2F;strong&gt;。根据&lt;strong&gt;强迫选择理论&lt;&#x2F;strong&gt;，当用户被迫在两个选项中抉择时，往往会选择 &lt;strong&gt;「最直接、最可控」的选项&lt;&#x2F;strong&gt;（剪标），而非被动忍受持续的不适感。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用认知偏差重构决策框架&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;用户在试穿时会下意识地认为「剪标是正常操作」，而非主动思考是否需要保留标签以退换货。这种设计利用了用户的&lt;strong&gt;现状偏见&lt;&#x2F;strong&gt;，即倾向于维持已发生的行为（剪标），而非主动改变现状（保留标签）。&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>如果人生是一场游戏</title>
          <pubDate>Sat, 03 Aug 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://clanedev.github.io/blog/posts/if-life-is-a-game/</link>
          <guid>https://clanedev.github.io/blog/posts/if-life-is-a-game/</guid>
          <description xml:base="https://clanedev.github.io/blog/posts/if-life-is-a-game/">&lt;blockquote&gt;
&lt;p&gt;活着就是为了追求最大的游戏体验&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;</description>
      </item>
    </channel>
</rss>
