import { jsx, jsxs, Fragment } from 'solid-jsx/jsx-runtime';

/*@jsxRuntime automatic @jsxImportSource solid-jsx*/
const toc = [{
  "depth": 1,
  "value": "TypeScript",
  "children": [{
    "depth": 2,
    "value": "配置 TypeScript",
    "children": []
  }, {
    "depth": 2,
    "value": "API 类型",
    "children": [{
      "depth": 3,
      "value": "Signals",
      "children": [{
        "depth": 5,
        "value": "默认",
        "children": []
      }]
    }, {
      "depth": 3,
      "value": "Context",
      "children": []
    }]
  }, {
    "depth": 2,
    "value": "组件类型",
    "children": []
  }, {
    "depth": 2,
    "value": "事件处理程序",
    "children": []
  }, {
    "depth": 2,
    "value": "ref 属性",
    "children": []
  }, {
    "depth": 2,
    "value": "控制流缩小",
    "children": []
  }, {
    "depth": 2,
    "value": "Special JSX Attributes and Directives",
    "children": [{
      "depth": 3,
      "value": "on:___/oncapture:___",
      "children": []
    }, {
      "depth": 3,
      "value": "prop:___/attr:___",
      "children": []
    }, {
      "depth": 3,
      "value": "use:___",
      "children": []
    }]
  }]
}];
function _createMdxContent(props) {
  const _components = Object.assign({
    h1: "h1",
    a: "a",
    p: "p",
    h2: "h2",
    code: "code",
    pre: "pre",
    span: "span",
    h3: "h3",
    h5: "h5",
    ol: "ol",
    li: "li"
  }, props.components);
  return jsxs(Fragment, {
    children: [jsxs(_components.h1, {
      id: "typescript",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#typescript",
        children: "#"
      }), "TypeScript"]
    }), "\n", jsx(_components.p, {
      children: "Solid 被设计为易于与 TypeScript 一起使用：它使用标准 JSX 使代码在很大程度上被 TypeScript 理解，并且它为其 API 提供了复杂的内置类型。本指南涵盖了使用 TypeScript 和编写 Solid 代码的一些有用技巧。"
    }), "\n", jsxs(_components.h2, {
      id: "配置-typescript",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#配置-typescript",
        children: "#"
      }), "配置 TypeScript"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.a, {
        href: "https://github.com/solidjs/templates/",
        children: "Solid starter templates"
      }), " 为 ", jsx(_components.a, {
        href: "https://github.com/solidjs/templates/blob/master/ts/tsconfig.json",
        children: jsx(_components.code, {
          children: "tsconfig.json"
        })
      }), " 提供了良好的起点"]
    }), "\n", jsxs(_components.p, {
      children: ["最重要的是，要将 TypeScript 与 Solid JSX 编译器一起使用，您需要通过 ", jsx(_components.a, {
        href: "https://www.typescriptlang.org/tsconfig#jsx",
        children: jsx(_components.code, {
          children: "\"jsx\": \"preserve\""
        })
      }), " 配置 TypeScript 以单独保留 JSX 结构， 并通过 ", jsx(_components.a, {
        href: "https://www.typescriptlang.org/tsconfig#jsxImportSource",
        children: jsx(_components.code, {
          children: "\"jsxImportSource\": \"solid-js\""
        })
      }), " 告诉 TypeScript JSX 类型来自哪里。所以，一个最小的 ", jsx(_components.code, {
        children: "tsconfig.json"
      }), " 看起来像这样："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-json",
        children: [jsx(_components.span, {
          className: "hljs-punctuation",
          children: "{"
        }), "\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "\"compilerOptions\""
        }), jsx(_components.span, {
          className: "hljs-punctuation",
          children: ":"
        }), " ", jsx(_components.span, {
          className: "hljs-punctuation",
          children: "{"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "\"jsx\""
        }), jsx(_components.span, {
          className: "hljs-punctuation",
          children: ":"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"preserve\""
        }), jsx(_components.span, {
          className: "hljs-punctuation",
          children: ","
        }), "\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "\"jsxImportSource\""
        }), jsx(_components.span, {
          className: "hljs-punctuation",
          children: ":"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), "\n  ", jsx(_components.span, {
          className: "hljs-punctuation",
          children: "}"
        }), "\n", jsx(_components.span, {
          className: "hljs-punctuation",
          children: "}"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["如果您的代码库混合使用 JSX 类型（例如，一些文件是 React 而其他文件是 Solid），您可以在 ", jsx(_components.code, {
        children: "tsconfig.json"
      }), " 中为大部分代码设置默认的 ", jsx(_components.code, {
        children: "jsxImportSource"
      }), "，然后 ", jsxs(_components.a, {
        href: "https://www.typescriptlang.org/tsconfig#jsxImportSource",
        children: ["覆盖 ", jsx(_components.code, {
          children: "jsxImportSource"
        }), " 选项"]
      }), " 在特定 ", jsx(_components.code, {
        children: ".tsx"
      }), " 文件中使用以下编译指示："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsxs(_components.span, {
          className: "hljs-comment",
          children: ["/** ", jsx(_components.span, {
            className: "hljs-doctag",
            children: "@jsxImportSource"
          }), " ", jsx(_components.span, {
            className: "hljs-variable",
            children: "solid"
          }), "-js */"]
        }), "\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "或"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsxs(_components.span, {
          className: "hljs-comment",
          children: ["/** ", jsx(_components.span, {
            className: "hljs-doctag",
            children: "@jsxImportSource"
          }), " react */"]
        }), "\n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "api-类型",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#api-类型",
        children: "#"
      }), "API 类型"]
    }), "\n", jsxs(_components.p, {
      children: ["Solid 是用 TypeScript 编写的，所以一切都是开箱即用的。", jsx(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api",
        children: "API 文档"
      }), " 详细介绍了所有 API 调用的类型，以及几个有用的类型定义，以便在需要指定显式类型时更轻松地引用 Solid 概念。在这里，我们在使用一些核心 API 时探索生成的类型。"]
    }), "\n", jsxs(_components.h3, {
      id: "signals",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#signals",
        children: "#"
      }), "Signals"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "createSignal<T>"
      }), " 由存储在 signal 中的对象的类型 ", jsx(_components.code, {
        children: "T"
      }), " 参数化。例如："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = createSignal<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ">();\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["第一个 ", jsx(_components.code, {
        children: "createSignal"
      }), " 的返回类型为 ", jsx(_components.code, {
        children: "Signal<number>"
      }), "，对应于我们传递给它的类型。这是 getter 和 setter 的元组，它们都有一个泛型类型："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " { ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Signal"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Accessor"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Setter"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Signal"
        }), "<T> = [", jsx(_components.span, {
          className: "hljs-attr",
          children: "get"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Accessor"
        }), "<T>, ", jsx(_components.span, {
          className: "hljs-attr",
          children: "set"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Setter"
        }), "<T>];\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这种情况下，signal getter ", jsx(_components.code, {
        children: "count"
      }), " 的类型为 ", jsx(_components.code, {
        children: "Accessor<number | undefined>"
      }), "。", jsx(_components.code, {
        children: "Accessor<T>"
      }), " 是 Solid 提供的类型定义，在这种情况下等同于 ", jsx(_components.code, {
        children: "() => number | undefined"
      }), "。在这个例子中添加了 ", jsx(_components.code, {
        children: "| undefined"
      }), "，因为我们没有为 ", jsx(_components.code, {
        children: "createSignal"
      }), " 提供默认值，所以 signal 值确实以 ", jsx(_components.code, {
        children: "undefined"
      }), " 开头。"]
    }), "\n", jsxs(_components.p, {
      children: ["signal setter ", jsx(_components.code, {
        children: "setCount"
      }), " 的类型是 ", jsx(_components.code, {
        children: "Setter<number>"
      }), "，这是一个比较复杂的类型定义，大致对应于 ", jsx(_components.code, {
        children: "(value?: number | ((prev?: number) => number)) => number"
      }), "，表示传递参数的两种可能性：您可以使用 ", jsx(_components.code, {
        children: "number"
      }), " 调用", jsx(_components.code, {
        children: "setCount"
      }), " 或使用前一个值（如果有的话）并返回 ", jsx(_components.code, {
        children: "number"
      }), " 的函数。"]
    }), "\n", jsxs(_components.p, {
      children: ["实际的 ", jsx(_components.code, {
        children: "Setter"
      }), " 类型更复杂，当您可能希望将 signal 设置为该函数值而不是调用函数以确定新值时，检测意外将函数传递给 setter。如果在调用 ", jsx(_components.code, {
        children: "setCount(value)"
      }), " 时遇到 TypeScript 错误 “Argument ... is not assignable to parameter”，请尝试将 setter 参数包装为 ", jsx(_components.code, {
        children: "setCount(() => value)"
      }), " 以确保 ", jsx(_components.code, {
        children: "value"
      }), " 没有被调用。"]
    }), "\n", jsxs(_components.h5, {
      id: "默认",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#默认",
        children: "#"
      }), "默认"]
    }), "\n", jsxs(_components.p, {
      children: ["我们可以避免在调用 ", jsx(_components.code, {
        children: "createSignal"
      }), " 时显式提供信号的类型，并通过为 ", jsx(_components.code, {
        children: "createSignal"
      }), " 提供默认值来避免类型的 ", jsx(_components.code, {
        children: "| undefined"
      }), " 部分："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), ");\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [name, setName] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "''"
        }), ");\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这种情况下，TypeScript 推断信号类型分别是 ", jsx(_components.code, {
        children: "number"
      }), " 和 ", jsx(_components.code, {
        children: "string"
      }), "。因此，例如，", jsx(_components.code, {
        children: "count"
      }), " 获得类型 ", jsx(_components.code, {
        children: "Accessor<number>"
      }), " 并且 ", jsx(_components.code, {
        children: "name"
      }), " 获得类型 ", jsx(_components.code, {
        children: "Accessor<string>"
      }), "（没有 ", jsx(_components.code, {
        children: "| undefined"
      }), "）。"]
    }), "\n", jsxs(_components.h3, {
      id: "context",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#context",
        children: "#"
      }), "Context"]
    }), "\n", jsxs(_components.p, {
      children: ["与 signal 类似，", jsx(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#createcontext",
        children: jsx(_components.code, {
          children: "createContext<T>"
        })
      }), " 由上下文值的类型 ", jsx(_components.code, {
        children: "T"
      }), " 参数化。我们可以明确地提供这种类型："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Data"
        }), " = {", jsx(_components.span, {
          className: "hljs-attr",
          children: "count"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ", ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), "};\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " dataContext = createContext<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Data"
        }), ">();\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这种情况下，", jsx(_components.code, {
        children: "dataContext"
      }), " 的类型为 ", jsx(_components.code, {
        children: "Context<Data | undefined>"
      }), "，导致 ", jsx(_components.code, {
        children: "useContext(dataContext)"
      }), " 具有匹配的返回类型 ", jsx(_components.code, {
        children: "Data | undefined"
      }), "。", jsx(_components.code, {
        children: "| undefined"
      }), " 的原因是当前组件的祖先可能没有提供上下文，在这种情况下，", jsx(_components.code, {
        children: "useContext"
      }), " 返回 ", jsx(_components.code, {
        children: "undefined"
      }), "。"]
    }), "\n", jsxs(_components.p, {
      children: ["如果我们改为为 ", jsx(_components.code, {
        children: "createContext"
      }), " 提供默认值，我们避免了类型的 ", jsx(_components.code, {
        children: "| undefined"
      }), " 部分，并且通常还避免了显式指定 ", jsx(_components.code, {
        children: "createContext"
      }), " 的类型："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " dataContext = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createContext"
        }), "({", jsx(_components.span, {
          className: "hljs-attr",
          children: "count"
        }), ": ", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), ", ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "''"
        }), "});\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这种情况下，TypeScript 推断 ", jsx(_components.code, {
        children: "dataContext"
      }), " 的类型为 ", jsx(_components.code, {
        children: "Context<{count: number, name: string}>"
      }), "，相当于 ", jsx(_components.code, {
        children: "Context<Data>"
      }), "（没有 ", jsx(_components.code, {
        children: "| undefined"
      }), "）。"]
    }), "\n", jsxs(_components.p, {
      children: ["另一种常见的模式是定义一个为上下文生成值的工厂函数。然后我们可以使用 TypeScript 的 ", jsx(_components.a, {
        href: "https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype",
        children: jsx(_components.code, {
          children: "ReturnType"
        })
      }), " 类型助手获取该函数的返回类型，并使用它来键入上下文 ："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "makeCountNameContext"
        }), " = (", jsxs(_components.span, {
          className: "hljs-params",
          children: ["initialCount = ", jsx(_components.span, {
            className: "hljs-number",
            children: "0"
          }), ", initialName = ", jsx(_components.span, {
            className: "hljs-string",
            children: "''"
          })]
        }), ") => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(initialCount);\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [name, setName] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(initialName);\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " [{count, name}, {setCount, setName}] ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "as"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), ";\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// `as const` 强制元组类型推断"
        }), "\n};\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CountNameContextType"
        }), " = ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ReturnType"
        }), "<", jsx(_components.span, {
          className: "hljs-keyword",
          children: "typeof"
        }), " makeCountNameContext>;\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CountNameContext"
        }), " = createContext<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CountNameContextType"
        }), ">();\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "useCountNameContext"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "useContext"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CountNameContext"
        }), ");\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在本例中，", jsx(_components.code, {
        children: "CountNameContextType"
      }), " 对应于 ", jsx(_components.code, {
        children: "makeCountNameContext"
      }), " 的返回值："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: ["[\n  {", jsx(_components.span, {
          className: "hljs-keyword",
          children: "readonly"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "count"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Accessor"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ">, ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "readonly"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Accessor"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ">},\n  {", jsx(_components.span, {
          className: "hljs-keyword",
          children: "readonly"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "setCount"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Setter"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ">, ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "readonly"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "setName"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Setter"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ">}\n]\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["并且 ", jsx(_components.code, {
        children: "useCountNameContext"
      }), " 的类型为 ", jsx(_components.code, {
        children: "() => CountNameContextType | undefined"
      }), "。"]
    }), "\n", jsxs(_components.p, {
      children: ["如果您想避免 ", jsx(_components.code, {
        children: "undefined"
      }), " 的可能性，您可以断言在使用时始终提供上下文："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "useCountNameContext"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "useContext"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CountNameContext"
        }), ")!;\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["这是一个危险的假设。实际上为", jsx(_components.code, {
        children: "createContext"
      }), "提供一个默认参数会更安全，以便始终定义上下文。"]
    }), "\n", jsxs(_components.h2, {
      id: "组件类型",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#组件类型",
        children: "#"
      }), "组件类型"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " { ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "<P = {}> = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "props: P"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "Element"
        }), ";\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["要键入基本组件函数，请使用 ", jsx(_components.code, {
        children: "Component<P>"
      }), " 类型，其中 ", jsx(_components.code, {
        children: "P"
      }), " 是 ", jsx(_components.code, {
        children: "props"
      }), " 参数的类型，应该是 ", jsx(_components.a, {
        href: "https://www.typescriptlang.org/docs/handbook/2/objects.html",
        children: "object type"
      }), "。这将强制正确类型的 props 作为属性传入，并且返回值可以由 Solid 呈现：", jsx(_components.code, {
        children: "JSX.Element"
      }), " 可以是 DOM 节点、", jsx(_components.code, {
        children: "JSX.Element"
      }), " 的数组、函数返回一个", jsx(_components.code, {
        children: "JSX.Element"
      }), "、一个布尔值、", jsx(_components.code, {
        children: "undefined"
      }), "/", jsx(_components.code, {
        children: "null"
      }), "等。这里有一些例子："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Counter"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), " = ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onClick"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{()"
            }), " =>"]
          }), " setCount((c) => c+1)}>\n      {count()}\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), ">"]
          })]
        }), "\n  );\n};\n\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), "/>"]
          })
        }), ";              ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// good"
        }), "\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "initial"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{5}/"
            }), ">"]
          })
        }), ";  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// type error: no initial prop"
        }), "\n", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), ">"]
          }), "hi", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), ">"]
          })]
        }), "    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// type error: no children prop"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "InitCounter"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "<{", jsx(_components.span, {
          className: "hljs-attr",
          children: "initial"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), "}> = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "props"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(props.", jsx(_components.span, {
          className: "hljs-property",
          children: "initial"
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onClick"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{()"
            }), " =>"]
          }), " setCount((c) => c+1)}>\n      {count()}\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), ">"]
          })]
        }), "\n  );\n};\n\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "InitCounter"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "initial"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{5}/"
            }), ">"]
          })
        }), ";  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// good"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["如果您希望组件采用 JSX children，您可以显式地将 ", jsx(_components.code, {
        children: "children"
      }), " 类型添加到 ", jsx(_components.code, {
        children: "P"
      }), " 中，或者您可以使用自动添加 ", jsx(_components.code, {
        children: "children?: JSX.Element"
      }), " 的 ", jsx(_components.code, {
        children: "ParentComponent"
      }), " 类型。或者，如果你想用 ", jsx(_components.code, {
        children: "function"
      }), " 而不是 ", jsx(_components.code, {
        children: "const"
      }), " 来声明你的组件，你可以使用 ", jsx(_components.code, {
        children: "ParentProps"
      }), " 帮助器来输入 ", jsx(_components.code, {
        children: "props"
      }), "。一些例子："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentComponent"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentProps"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentProps"
        }), "<P = {}> = P & { children?: ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "Element"
        }), " };\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentComponent"
        }), "<P = {}> = ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentProps"
        }), "<P>>;\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 等效类型:"
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "//const CustomCounter: Component<{children?: JSX.Element}> = ..."
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "//function CustomCounter(props: ParentProps): JSX.Element { ..."
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CustomCounter"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentComponent"
        }), " = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "props"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onClick"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{()"
            }), " =>"]
          }), " setCount((c) => c+1)}>\n      {count()}\n      {props.children}\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), ">"]
          })]
        }), "\n  );\n};\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 等效类型:"
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "//const CustomInitCounter: Component<{initial: number, children?: JSX.Element}> = ..."
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "//function CustomInitCounter(props: ParentProps<{initial: number}>): JSX.Element { ..."
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CustomInitCounter"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ParentComponent"
        }), "<{", jsx(_components.span, {
          className: "hljs-attr",
          children: "initial"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), "}> = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "props"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(props.", jsx(_components.span, {
          className: "hljs-property",
          children: "initial"
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onClick"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{()"
            }), " =>"]
          }), " setCount((c) => c+1)}>\n      {count()}\n      {props.children}\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "button"
            }), ">"]
          })]
        }), "\n  );\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在后一个示例中，", jsx(_components.code, {
        children: "props"
      }), " 参数自动输入为 ", jsx(_components.code, {
        children: "props: ParentProps<{initial: number}>"
      }), "，相当于 ", jsx(_components.code, {
        children: "props: {initial: number, children?: JSX.Element}"
      }), "。（注意，在 Solid 1.4 之前，", jsx(_components.code, {
        children: "Component"
      }), " 等同于 ", jsx(_components.code, {
        children: "ParentComponent"
      }), "。）"]
    }), "\n", jsxs(_components.p, {
      children: ["Solid 提供了另外两个 ", jsx(_components.code, {
        children: "Component"
      }), " 子类型来处理 ", jsx(_components.code, {
        children: "children"
      }), "："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " {", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowComponent"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowProps"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "VoidComponent"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "VoidProps"
        }), "} ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowProps"
        }), "<P = {}, C = ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "Element"
        }), "> = P & { ", jsx(_components.span, {
          className: "hljs-attr",
          children: "children"
        }), ": C };\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowComponent"
        }), "<P = {}, C = ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "Element"
        }), "> = ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowProps"
        }), "<P, C>>;\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "VoidProps"
        }), "<P = {}> = P & { children?: ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "never"
        }), " };\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "VoidComponent"
        }), "<P = {}> = ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "VoidProps"
        }), "<P>>;\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "Void Component"
      }), " 适用于绝对不支持 ", jsx(_components.code, {
        children: "children"
      }), " 的组件。当 ", jsx(_components.code, {
        children: "P"
      }), " 没有为 ", jsx(_components.code, {
        children: "children"
      }), " 提供类型时，", jsx(_components.code, {
        children: "Void Component<P>"
      }), " 等价于 ", jsx(_components.code, {
        children: "Component<P>"
      }), "。"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "FlowComponent"
      }), " 用于 “控制流” 组件，例如 Solid 的 ", jsx(_components.code, {
        children: "<Show>"
      }), " 和 ", jsx(_components.code, {
        children: "<For>"
      }), "。这样的组件通常需要 ", jsx(_components.code, {
        children: "children"
      }), " 才有意义，并且有时有 ", jsx(_components.code, {
        children: "children"
      }), " 的特定类型，例如要求它是单个函数。例如："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CallMeMaybe"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "FlowComponent"
        }), "<{", jsx(_components.span, {
          className: "hljs-attr",
          children: "when"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "boolean"
        }), "}, ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), "> = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "props"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "if"
        }), " (props.", jsx(_components.span, {
          className: "hljs-property",
          children: "when"
        }), ")\n      props.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "children"
        }), "();\n  });\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsx(_components.span, {
            className: "hljs-tag",
            children: "<>"
          }), "{props.when ? 'Calling' : 'Not Calling'}", jsx(_components.span, {
            className: "hljs-tag",
            children: "</>"
          })]
        }), ";\n};\n\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "CallMeMaybe"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "when"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{true}/"
            }), ">"]
          })
        }), ";  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// type error: missing children"
        }), "\n", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "CallMeMaybe"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "when"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{true}"
            }), ">"]
          }), "hi", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "CallMeMaybe"
            }), ">"]
          })]
        }), ";  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// type error: children"
        }), "\n", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "CallMeMaybe"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "when"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{true}"
            }), ">"]
          }), "\n  {() => console.log(\"Here's my number\")}\n", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "CallMeMaybe"
            }), ">"]
          })]
        }), ";              ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// good"
        }), "\n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "事件处理程序",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#事件处理程序",
        children: "#"
      }), "事件处理程序"]
    }), "\n", jsxs(_components.p, {
      children: ["命名空间 ", jsx(_components.code, {
        children: "JSX"
      }), " 提供了一套特别适用于 HTML DOM 的有用类型。请参阅 ", jsx(_components.a, {
        href: "https://github.com/ryansolid/dom-expressions/blob/main/packages/dom-expressions/src/jsx.d.ts",
        children: "dom-expressions 中 JSX 的定义"
      }), " 了解提供的所有类型。"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "JSX"
      }), " 命名空间提供的一种有用的帮助类型是 ", jsx(_components.code, {
        children: "JSX.EventHandler<T, E>"
      }), "，它表示 DOM 元素类型 ", jsx(_components.code, {
        children: "T"
      }), " 和事件类型 ", jsx(_components.code, {
        children: "E"
      }), " 的单参数事件处理程序。您可以使用它来键入您在 JSX 之外定义的任何事件处理程序。例如："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "type"
        }), " { ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "onInput"
        }), ": ", jsx(_components.span, {
          className: "hljs-variable constant_",
          children: "JSX"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "EventHandler"
        }), "<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "HTMLInputElement"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "InputEvent"
        }), "> = ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "event"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "console"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "log"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'input changed to'"
        }), ", event.", jsx(_components.span, {
          className: "hljs-property",
          children: "currentTarget"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), ");\n};\n\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "input"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onInput"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{onInput}/"
            }), ">"]
          })
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在 ", jsxs(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#on___",
        children: [jsx(_components.code, {
          children: "on___"
        }), " JSX 属性"]
      }), " 中内联定义的处理程序（具有内置事件类型）会自动键入适当的 ", jsx(_components.code, {
        children: "JSX.EventHandler"
      }), "："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: ["<input onInput={", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "event"
          }), ") =>"]
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "console"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "log"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'input changed to'"
        }), ", event.", jsx(_components.span, {
          className: "hljs-property",
          children: "currentTarget"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), ");\n}}/>;\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["请注意，", jsx(_components.code, {
        children: "JSX.EventHandler<T>"
      }), " 将事件的 ", jsxs(_components.a, {
        href: "https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget",
        children: [jsx(_components.code, {
          children: "currentTarget"
        }), " 属性"]
      }), " 限制为类型为 ", jsx(_components.code, {
        children: "T "
      }), "（在示例中，", jsx(_components.code, {
        children: "event.currentTarget"
      }), " 的类型为 ", jsx(_components.code, {
        children: "HTMLInputEvent"
      }), "，因此具有属性 ", jsx(_components.code, {
        children: "value"
      }), "）。但是，事件的 ", jsxs(_components.a, {
        href: "https://developer.mozilla.org/en-US/docs/Web/API/Event/target",
        children: [jsx(_components.code, {
          children: "target"
        }), " 属性"]
      }), " 可以是任何 ", jsx(_components.code, {
        children: "DOMElement"
      }), "。这是因为 ", jsx(_components.code, {
        children: "currentTarget"
      }), " 是事件处理程序附加到的元素，因此具有已知类型，而 ", jsx(_components.code, {
        children: "target"
      }), " 是用户与之交互的任何内容，导致事件冒泡或被事件处理程序捕获，这可以是任何 DOM 元素。"]
    }), "\n", jsxs(_components.h2, {
      id: "ref-属性",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#ref-属性",
        children: "#"
      }), "ref 属性"]
    }), "\n", jsxs(_components.p, {
      children: ["当我们使用带有变量的 ", jsx(_components.code, {
        children: "ref"
      }), " 属性时，我们告诉 Solid 在元素渲染后将 DOM 元素分配给变量。如果没有 TypeScript，这看起来像："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " divRef;\n\n", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "console"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "log"
        }), "(divRef); ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// undefined"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "onMount"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "console"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "log"
        }), "(divRef); ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// <div> element"
        }), "\n})\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n  ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "ref"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{divRef}/"
            }), ">"]
          })
        }), "\n)\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["这对键入该变量提出了挑战：我们是否应该将 ", jsx(_components.code, {
        children: "divRef"
      }), " 键入为 ", jsx(_components.code, {
        children: "HTMLDivElement"
      }), "，即使它只是在渲染后才设置的？（这里我们假设 TypeScript 的 ", jsx(_components.code, {
        children: "strictNullChecks"
      }), " 模式已打开；否则，TypeScript 会忽略潜在的 ", jsx(_components.code, {
        children: "undefined"
      }), " 变量。）"]
    }), "\n", jsxs(_components.p, {
      children: ["TypeScript 中最安全的模式是在一段时间内确认 ", jsx(_components.code, {
        children: "divRef"
      }), " 为 ", jsx(_components.code, {
        children: "undefined"
      }), "，并在使用时进行检查："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "divRef"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "HTMLDivElement"
        }), " | ", jsx(_components.span, {
          className: "hljs-literal",
          children: "undefined"
        }), ";\n\ndivRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 在编译时正确报告为错误"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "onMount"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "if"
        }), " (!divRef) ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), ";\n  divRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 正确允许"
        }), "\n});\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "ref"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{divRef!}"
            }), ">"]
          }), "\n    ...\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), "\n);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["或者，因为我们知道 ", jsx(_components.code, {
        children: "onMount"
      }), " 仅在 ", jsx(_components.code, {
        children: "<div>"
      }), " 元素被渲染后才被调用，在 ", jsx(_components.code, {
        children: "onMount"
      }), " 中访问 ", jsx(_components.code, {
        children: "divRef"
      }), " 时，我们可以使用 ", jsxs(_components.a, {
        href: "https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#non-null-assertion-operator-postfix-",
        children: ["非空断言 (", jsx(_components.code, {
          children: "!"
        }), ")"]
      }), " ："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-title function_",
          children: "onMount"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  divRef!.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();\n});\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["另一个相当安全的模式是从 ", jsx(_components.code, {
        children: "divRef"
      }), " 的类型中省略 ", jsx(_components.code, {
        children: "undefined"
      }), "，并在 ", jsx(_components.code, {
        children: "ref"
      }), " 属性中使用 ", jsxs(_components.a, {
        href: "https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions",
        children: ["确定赋值断言 (", jsx(_components.code, {
          children: "!"
        }), ")"]
      }), "："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "divRef"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "HTMLDivElement"
        }), ";\n\ndivRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 在编译时正确报告为错误"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "onMount"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  divRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 正确允许"
        }), "\n});\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "ref"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{divRef!}"
            }), ">"]
          }), "\n    ...\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), "\n);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["我们需要使用 ", jsx(_components.code, {
        children: "ref={divRef!}"
      }), "，因为 TypeScript 假定 ", jsx(_components.code, {
        children: "ref"
      }), " 属性被设置为 ", jsx(_components.code, {
        children: "divRef"
      }), " 变量，因此应该已经分配了 ", jsx(_components.code, {
        children: "divRef"
      }), "。在 Solid 中，情况正好相反：", jsx(_components.code, {
        children: "divRef"
      }), " 由 ", jsx(_components.code, {
        children: "ref"
      }), " 属性分配。明确的赋值断言 ", jsx(_components.code, {
        children: "divRef!"
      }), " 有效地让 TypeScript 相信这是正在发生的事情：TypeScript 将理解在这一行之后已经分配了 ", jsx(_components.code, {
        children: "divRef"
      }), "。"]
    }), "\n", jsxs(_components.p, {
      children: ["使用这种模式，TypeScript 将正确地标记函数体内任何意外使用 refs（在定义它们的 JSX 块之前）。但是，TypeScript 目前没有标记嵌套函数中潜在未定义变量的使用。在 Solid 的上下文中，您需要注意不要在 ", jsx(_components.code, {
        children: "createMemo"
      }), "、", jsx(_components.code, {
        children: "createRenderEffect"
      }), " 和 ", jsx(_components.code, {
        children: "createComputed"
      }), " 中使用 refs（在定义 refs 的 JSX 块之前），因为这些函数会立即调用，所以 refs 不会被定义（但 TypeScript 不会将此标记为错误）。相比之下，之前的模式会捕获这些错误。"]
    }), "\n", jsx(_components.p, {
      children: "另一种常见但不太安全的模式是将明确的赋值断言放在变量声明的位置。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " divRef!: ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "HTMLDivElement"
        }), ";\n\ndivRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 尽管导致错误，但仍允许"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "onMount"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  divRef.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "focus"
        }), "();  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 正确允许"
        }), "\n});\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "ref"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{divRef}"
            }), ">"]
          }), "\n    ...\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), "\n);\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "这种方法有效地关闭了对该变量的赋值检查，这是一种简单的解决方法，但需要额外注意。特别是，与之前的模式不同，它错误地允许过早使用变量，甚至在嵌套函数之外。"
    }), "\n", jsxs(_components.h2, {
      id: "控制流缩小",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#控制流缩小",
        children: "#"
      }), "控制流缩小"]
    }), "\n", jsxs(_components.p, {
      children: ["一种常见的模式是仅在定义数据时使用 ", jsx(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#%3Cshow%3E",
        children: jsx(_components.code, {
          children: "<Show>"
        })
      }), " 来显示数据："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [name, setName] = createSignal<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ">();\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Show"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "when"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{name()}"
            }), ">"]
          }), "\n    Hello {name().replace(/\\s+/g, '\\xa0')}!\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Show"
            }), ">"]
          })]
        }), "\n);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这种情况下，TypeScript 无法确定对 ", jsx(_components.code, {
        children: "name()"
      }), " 的两次调用是否会返回相同的值，并且只有在第一次调用返回真值时才会发生第二次调用。因此它会在尝试调用 ", jsx(_components.code, {
        children: ".replace()"
      }), " 时抱怨 ", jsx(_components.code, {
        children: "name()"
      }), " 可能是 ", jsx(_components.code, {
        children: "undefined"
      }), "。"]
    }), "\n", jsx(_components.p, {
      children: "以下是针对此问题的两种解决方法："
    }), "\n", jsxs(_components.ol, {
      children: ["\n", jsxs(_components.li, {
        children: ["\n", jsxs(_components.p, {
          children: ["您可以使用 TypeScript 的 ", jsxs(_components.a, {
            href: "https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#non-null-assertion-operator-postfix-",
            children: ["非空断言运算符 ", jsx(_components.code, {
              children: "!"
            })]
          }), " 在第二次调用中手动断言 ", jsx(_components.code, {
            children: "name()"
          }), " 将是非空的："]
        }), "\n", jsx(_components.pre, {
          children: jsxs(_components.code, {
            className: "hljs language-tsx",
            children: [jsx(_components.span, {
              className: "hljs-keyword",
              children: "return"
            }), " (\n  ", jsxs(_components.span, {
              className: "xml",
              children: [jsxs(_components.span, {
                className: "hljs-tag",
                children: ["<", jsx(_components.span, {
                  className: "hljs-name",
                  children: "Show"
                }), " ", jsx(_components.span, {
                  className: "hljs-attr",
                  children: "when"
                }), "=", jsx(_components.span, {
                  className: "hljs-string",
                  children: "{name()}"
                }), ">"]
              }), "\n    Hello {name()!.replace(/\\s+/g, '\\xa0')}!\n  ", jsxs(_components.span, {
                className: "hljs-tag",
                children: ["</", jsx(_components.span, {
                  className: "hljs-name",
                  children: "Show"
                }), ">"]
              })]
            }), "\n);\n"]
          })
        }), "\n"]
      }), "\n", jsxs(_components.li, {
        children: ["\n", jsxs(_components.p, {
          children: ["可以使用 ", jsx(_components.code, {
            children: "<Show>"
          }), " 的回调形式，当它为真时传入 ", jsx(_components.code, {
            children: "when"
          }), " 属性的值："]
        }), "\n", jsx(_components.pre, {
          children: jsxs(_components.code, {
            className: "hljs language-tsx",
            children: [jsx(_components.span, {
              className: "hljs-keyword",
              children: "return"
            }), " (\n  ", jsxs(_components.span, {
              className: "xml",
              children: [jsxs(_components.span, {
                className: "hljs-tag",
                children: ["<", jsx(_components.span, {
                  className: "hljs-name",
                  children: "Show"
                }), " ", jsx(_components.span, {
                  className: "hljs-attr",
                  children: "when"
                }), "=", jsx(_components.span, {
                  className: "hljs-string",
                  children: "{name()}"
                }), ">"]
              }), "\n    {(n) =>\n      ", jsx(_components.span, {
                className: "hljs-tag",
                children: "<>"
              }), "Hello {n.replace(/\\s+/g, '\\xa0')}!", jsx(_components.span, {
                className: "hljs-tag",
                children: "</>"
              })]
            }), "\n    }\n  </", jsx(_components.span, {
              className: "hljs-title class_",
              children: "Show"
            }), ">\n);\n"]
          })
        }), "\n", jsxs(_components.p, {
          children: ["在这种情况下，", jsx(_components.code, {
            children: "Show"
          }), " 组件的类型足够聪明，可以告诉 TypeScript ", jsx(_components.code, {
            children: "n"
          }), " 是真的，所以它不能是 ", jsx(_components.code, {
            children: "undefined"
          }), "（或 ", jsx(_components.code, {
            children: "null"
          }), " 或 ", jsx(_components.code, {
            children: "false"
          }), "）。"]
        }), "\n", jsxs(_components.p, {
          children: ["但是请注意，这种形式的 ", jsx(_components.code, {
            children: "<Show>"
          }), " 会在每次 ", jsx(_components.code, {
            children: "name()"
          }), " 更改时强制所有子级从头开始渲染，而不是只在 ", jsx(_components.code, {
            children: "name()"
          }), " 从假值变为真值时这样做。这意味着 children 没有获得细粒度响应性的全部好处（重新使用未更改的部分并更新已更改的部分）。"]
        }), "\n"]
      }), "\n"]
    }), "\n", jsxs(_components.h2, {
      id: "special-jsx-attributes-and-directives",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#special-jsx-attributes-and-directives",
        children: "#"
      }), "Special JSX Attributes and Directives"]
    }), "\n", jsxs(_components.h3, {
      id: "on___oncapture___",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#on___oncapture___",
        children: "#"
      }), jsx(_components.code, {
        children: "on:___"
      }), "/", jsx(_components.code, {
        children: "oncapture:___"
      })]
    }), "\n", jsxs(_components.p, {
      children: ["如果您通过 Solid 的 ", jsxs(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#on%3A___%2Foncapture%3A___",
        children: [jsx(_components.code, {
          children: "on:___"
        }), "/", jsx(_components.code, {
          children: "oncapture:___"
        }), " 属性"]
      }), " 使用自定义事件处理程序，您应该通过覆盖模块 ", jsx(_components.code, {
        children: "\"solid -js\""
      }), "的", jsx(_components.code, {
        children: "JSX"
      }), "命名空间，像这样："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "class"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "NameEvent"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "extends"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_ inherited__",
          children: "CustomEvent"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "type"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "'Name'"
        }), ";\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "detail"
        }), ": {", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), "};\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "constructor"
        }), "(", jsxs(_components.span, {
          className: "hljs-params",
          children: ["name: ", jsx(_components.span, {
            className: "hljs-built_in",
            children: "string"
          })]
        }), ") {\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "super"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'Name'"
        }), ", {", jsx(_components.span, {
          className: "hljs-attr",
          children: "detail"
        }), ": {name}});\n  }\n}\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "declare"
        }), " ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "module"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "namespace"
        }), " JSX {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "interface"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CustomEvents"
        }), " { ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// on:Name"
        }), "\n      ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Name\""
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "NameEvent"
        }), ";\n    }\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "interface"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "CustomCaptureEvents"
        }), " { ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// oncapture:Name"
        }), "\n      ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Name\""
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "NameEvent"
        }), ";\n    }\n  }\n}\n\n<div ", jsx(_components.span, {
          className: "hljs-attr",
          children: "on"
        }), ":", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Name"
        }), "={", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "event"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "console"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "log"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'name is'"
        }), ", event.", jsx(_components.span, {
          className: "hljs-property",
          children: "detail"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "name"
        }), ")}/>\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "prop___attr___",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#prop___attr___",
        children: "#"
      }), jsx(_components.code, {
        children: "prop:___"
      }), "/", jsx(_components.code, {
        children: "attr:___"
      })]
    }), "\n", jsxs(_components.p, {
      children: ["如果您通过 Solid 的 ", jsxs(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#prop%3A___",
        children: [jsx(_components.code, {
          children: "prop:___"
        }), " 属性"]
      }), " 使用强制属性，或通过 Solid 的 ", jsxs(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#attr%3A___",
        children: [jsx(_components.code, {
          children: "attr:___"
        }), " 属性"]
      }), " 使用自定义属性，则可以分别在 ", jsx(_components.code, {
        children: "ExplicitProperties"
      }), " 和 ", jsx(_components.code, {
        children: "ExplicitAttributes"
      }), " 接口中定义它们的类型："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "declare"
        }), " ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "module"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "namespace"
        }), " JSX {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "interface"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ExplicitProperties"
        }), " { ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// prop:___"
        }), "\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "count"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ";\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ";\n    }\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "interface"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "ExplicitAttributes"
        }), " { ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// attr:___"
        }), "\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "count"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "number"
        }), ";\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ";\n    }\n  }\n}\n\n<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Input"
        }), " ", jsx(_components.span, {
          className: "hljs-attr",
          children: "prop"
        }), ":name={", jsx(_components.span, {
          className: "hljs-title function_",
          children: "name"
        }), "()} ", jsx(_components.span, {
          className: "hljs-attr",
          children: "prop"
        }), ":count={", jsx(_components.span, {
          className: "hljs-title function_",
          children: "count"
        }), "()}/>\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "my-web-component"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "attr:name"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{name()}"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "attr:count"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{count()}/"
            }), ">"]
          })
        }), "\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "use___",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#use___",
        children: "#"
      }), jsx(_components.code, {
        children: "use:___"
      })]
    }), "\n", jsxs(_components.p, {
      children: ["如果您为 Solid 的 ", jsxs(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#use%3A___",
        children: [jsx(_components.code, {
          children: "use:___"
        }), " 属性"]
      }), " 定义自定义指令，您可以在 ", jsx(_components.code, {
        children: "Directives"
      }), " 界面中键入它们，如下所示 ："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-tsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "function"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "model"
        }), "(", jsxs(_components.span, {
          className: "hljs-params",
          children: ["element: HTMLInputElement, value: Accessor<Signal<", jsx(_components.span, {
            className: "hljs-built_in",
            children: "string"
          }), ">>"]
        }), ") {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [field, setField] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "value"
        }), "();\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRenderEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " (element.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), " = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "field"
        }), "()));\n  element.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "addEventListener"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"input\""
        }), ", ", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "e"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setField"
        }), "(e.", jsx(_components.span, {
          className: "hljs-property",
          children: "target"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), "));\n}\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "declare"
        }), " ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "module"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "namespace"
        }), " JSX {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "interface"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Directives"
        }), " {  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// use:model"
        }), "\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "model"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Signal"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "string"
        }), ">;\n    }\n  }\n}\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " [name, setName] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "''"
        }), ");\n\n", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "input"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "type"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"text\""
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "use:model"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{[name,"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "setName"
            }), "]} />"]
          })
        }), ";\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["如果你从另一个模块中导入指令 ", jsx(_components.code, {
        children: "d"
      }), "，并且 ", jsx(_components.code, {
        children: "d"
      }), " 仅用作指令 ", jsx(_components.code, {
        children: "use:d"
      }), "，那么 TypeScript（或更准确地说，", jsx(_components.a, {
        href: "https://babeljs.io/docs/en/babel-preset-typescript",
        children: jsx(_components.code, {
          children: "babel-preset-typescript"
        })
      }), "） 默认情况下会删除 ", jsx(_components.code, {
        children: "d"
      }), " 的 ", jsx(_components.code, {
        children: "import"
      }), "（因为担心 ", jsx(_components.code, {
        children: "d"
      }), " 是一种类型，因为 TypeScript 不理解 ", jsx(_components.code, {
        children: "use:d"
      }), " 作为对 ", jsx(_components.code, {
        children: "d"
      }), " 的引用）。有两种方法可以解决这个问题："]
    }), "\n", jsxs(_components.ol, {
      children: ["\n", jsxs(_components.li, {
        children: ["\n", jsxs(_components.p, {
          children: ["使用 [", jsx(_components.code, {
            children: "babel-preset-typescript"
          }), " 的 ", jsx(_components.code, {
            children: "onlyRemoveTypeImports: true"
          }), "] 配置选项，它可以防止删除除 ", jsx(_components.code, {
            children: "import type ..."
          }), " 之外的任何 ", jsx(_components.code, {
            children: "import"
          }), "。如果你使用 ", jsx(_components.code, {
            children: "vite-plugin-solid"
          }), "，你可以通过 ", jsx(_components.code, {
            children: "vite.config.ts"
          }), " 中的 ", jsx(_components.code, {
            children: "solidPlugin({ typescript: { onlyRemoveTypeImports: true } })"
          }), " 指定这个选项。"]
        }), "\n", jsxs(_components.p, {
          children: ["请注意，如果您没有在整个代码库中谨慎地使用 ", jsx(_components.code, {
            children: "export type"
          }), " 和 ", jsx(_components.code, {
            children: "import type"
          }), "，则此选项可能会出现问题。"]
        }), "\n"]
      }), "\n", jsxs(_components.li, {
        children: ["\n", jsxs(_components.p, {
          children: ["为每个模块 ", jsx(_components.code, {
            children: "import"
          }), " 指令 ", jsx(_components.code, {
            children: "d"
          }), " 添加一个虚假访问，例如 ", jsx(_components.code, {
            children: "false && d;"
          }), "。这将阻止 TypeScript 删除 ", jsx(_components.code, {
            children: "d"
          }), " 的 ", jsx(_components.code, {
            children: "import"
          }), "，并假设您通过例如 ", jsx(_components.code, {
            children: "Terser"
          }), " 进行 tree-shaking，此代码将从您的最终代码包中省略。"]
        }), "\n", jsxs(_components.p, {
          children: ["更简单的假访问 ", jsx(_components.code, {
            children: "d;"
          }), " 也将阻止 ", jsx(_components.code, {
            children: "import"
          }), " 被删除，但通常不会被摇树掉，因此最终会出现在您的最终代码包中。"]
        }), "\n"]
      }), "\n"]
    })]
  });
}
function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || ({});
  return MDXLayout ? jsx(MDXLayout, Object.assign({}, props, {
    children: jsx(_createMdxContent, props)
  })) : _createMdxContent(props);
}

export { MDXContent as default, toc };
//# sourceMappingURL=typescript-8a28622f.js.map
