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

如何使JSX工厂函数成为typescript项目的全局函数?,typescript,jsx,typescript-typings,Typescript,Jsx,Typescript Typings,我将按照以下步骤在一个辅助项目中设置和使用JSXsans React 我遇到了一件非常恼人的事情:我找不到任何关于如何在整个项目中全局公开JSX工厂函数的内容。另外(尽管不那么重要),我的JSX.intrinsiceelements结构也没有被全局公开 这是我的tsconfig: { "compileOnSave": true, "compilerOptions": { "target": "es6", "lib": [ "

我将按照以下步骤在一个辅助项目中设置和使用JSXsans React

我遇到了一件非常恼人的事情:我找不到任何关于如何在整个项目中全局公开JSX工厂函数的内容。另外(尽管不那么重要),我的
JSX.intrinsiceelements
结构也没有被全局公开

这是我的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
    }
}
我在其中声明我的
图像
元素的文件:

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

import {image} from "./image";

image({src: "google.com"})
src/image.tsx:13:9-错误TS7026:JSX元素隐式具有类型“any”,因为不存在接口“JSX.IntrinsicElements”。
13
~~~~~~~

如果要使函数成为全局函数,请不要使用
导出
关键字,这将使当前文件成为一个模块,因此需要显式导入函数。类似地,
JSX
名称空间需要是全局的,因此如果它是在模块中定义的,则需要在全局名称空间中显式声明:

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 />
           ~~~~~~~
如果您想走全球路线,这将起作用:

declare global {
    namespace JSX {
        interface IntrinsicElements {
            image: any
        }
    }
}
//jsxinfrastructure.ts
函数generateElement(标记:字符串,属性:字符串[]){
返回文档.createElement(标记)
}
声明命名空间JSX{
接口内部元素{
图片:任何
}
}
//用法
导出函数映像(prop:{src:string}){
返回(
)
}
如果希望jsx factory函数位于模块内,则需要导入函数:

// 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 />
    )
}
//jsxinfrastructure.ts
导出函数generateElement(标记:字符串,属性:字符串[]){
返回文档.createElement(标记)
}
宣布全球{
名称空间JSX{
接口内部元素{
图片:任何
}
}
}
//用法
从“/jsxinfrastructure”导入{generateElement}
导出函数映像(prop:{src:string}){
返回(
)
}

基本思想是,工厂函数需要在使用JSX标记的上下文中可用(如果可以调用
generateeElement
JSX也可以)。帮助我声明
import{jsx}来自'@emotion/react/jsx runtime'
,它是使用自定义类型脚本转换器(emotion-ts-loader)使用webpack自动插入的:
import{createElement}来自'@types/react';通过tsconfig.json选项
“types”:[“/typings/index”],
/*要包含在编译中的类型声明文件,声明全局{var jsx:typeof createElement=createElement;}
*/
// 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 />
    )
}