typescript - 如何使 JSX 工厂函数成为 typescript 项目的全局函数?

标签 typescript jsx typescript-typings

我正在关注 TypeScript JSX guide在副项目中设置和使用 JSX sans React

有一件事让我非常恼火:我找不到任何关于如何将 JSX 工厂函数全局公开给整个项目的提及。此外(虽然不那么重要),我的 JSX.IntrinsicElements 结构也没有全局公开。

这是我的 tsconfig:

{
    "compileOnSave": true,
    "compilerOptions": {
        "target": "es6",
        "lib": [
            "dom",
            "es2015"
        ],
        "experimentalDecorators": true,
        "jsx": "react",
        "jsxFactory": "generateElement",
        "sourceMap": true,
        "noImplicitAny": true,
        "pretty": true,
        "importHelpers": true,
        "outDir": "dist"
    },
    "include": ["./src/**/*.ts", "./src/**/*.tsx"]
}

我在其中声明 generateElement 的文件:

export function generateElement(tag: string, attrs: string[]) {
    return document.createElement(tag)
}

declare namespace JSX {
    interface IntrinsicElements {
        image: any
    }
}

我在其中声明我的 image 元素的文件:

export function image(prop: {src: string}) {
    return (
        <img />
    )
}

以及项目的主要入口点,我尝试在其中导入我的元素:

import {image} from "./image";

image({src: "google.com"})

错误:

src/image.tsx:13:9 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

13         <img />
           ~~~~~~~


src/image.tsx:13:10 - error TS2304: Cannot find name 'generateElement'.

13         <img />
           ~~~~~~~

最佳答案

如果你想让这个函数成为全局函数,不要使用export关键字,这将使当前文件成为一个模块,因此需要显式导入函数。同样,JSX命名空间需要是全局的,所以如果在模块中定义,需要在全局命名空间中显式声明:

declare global {
    namespace JSX {
        interface IntrinsicElements {
            image: any
        }
    }
}

如果你想走全局路线,这会奏效:

// jsxinfrastructure.ts
function generateElement(tag: string, attrs: string[]) {
    return document.createElement(tag)
}

declare namespace JSX {
    interface IntrinsicElements {
        image: any
    }
}

// usage.ts
export function image(prop: {src: string}) {
    return (
        <image />
    )
}

如果您希望 jsx 工厂函数位于模块中,则需要导入该函数:

// jsxinfrastructure.ts
export function generateElement(tag: string, attrs: string[]) {
    return document.createElement(tag)
}
declare global {
    namespace JSX {
        interface IntrinsicElements {
            image: any
        }
    }
}


// usage.ts
import { generateElement } from './jsxinfrastructure'
export function image(prop: {src: string}) {
    return (
        <image />
    )
}

基本思想是工厂函数需要在您使用 JSX 标签的上下文中可用(如果您可以调用 generateElement jsx 也可以)。

关于typescript - 如何使 JSX 工厂函数成为 typescript 项目的全局函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50806690/

相关文章:

angularjs - 安装下划线类型时出错

javascript - TS TypeScript SetInterval - 无法从计时器目标函数内部访问函数

javascript - 即使在将数字显式转换为字符串变量后,Angular 仍然编译没有错误

javascript - 无法读取未定义错误的属性 'match'

javascript - 模板文字作为 JSX 中的字符串内容

typescript - 在 typescript 中输入接收对象键值对的回调

typescript - 如何将 TypeScript tsconfig 放在另一个位置

node.js - 使用 ASP.Net Core 应用程序填充 Angular 上的下拉列表时出现错误 TS2717

javascript - 如何在 React JSX 中打印子字符串?

typescript - TS中的keyof数组类型很奇怪