There is an abstract interface JSX in the global namespace Some types in the JSX interface
declare global {
namespace JSX {
// 标签集合接口,定义了可用的标签类型和对应属性。(需要你实现。)
type IntrinsicElements = {};
// JSX.Element 接口(需要你实现。)
interface Element {}
// Children 类型接口,用于对闭合标签中children做类型检查。(需要你实现。)
interface ElementChildrenAttribute {}
}
}
JSX tag collection interface, similar to HTMLElementTagNameMap
declare global {
namespace JSX {
type IntrinsicElements = {
view: { bindtap?: Function };
richText: { bindtap?: Function };
text: { bindtap?: Function };
label: { bindtap?: Function };
navigator: { bindtap?: Function };
};
}
}
Implement the tag signature and the corresponding attributes in global::JSX::IntrinsicElements, and then the JSX tags in the .tsx file will have type prompts such as view and richText, and all prompt for an optional bindtap attribute. For example
function App() {
return (
<view>
<text bindtap={() => console.log("click")} />
<text />
</view>
);
}
Because they all have bindtap attributes, you can extract them directly, and then use mapped type to merge the value of each property in the TagNameMap collection into a Base base type to get a new collection type, IntrinsicElements.
similar to Functor, apply the
& Base
operation to each value in the TagNameMap category, and then get a new category IntrinsicElements
// TagNameMap 范畴
type TagNameMap = {
view: {};
richText: {};
text: {};
label: {};
navigator: {};
};
type Base = {
bindtap?: Function;
};
declare global {
namespace JSX {
// IntrinsicElements 范畴
type IntrinsicElements = {
[Tag in keyof TagNameMap]: TagNameMap[Tag] & Base
};
}
}
What is it used for? for example, 8 Expand on the basis of the above example
declare global {
namespace JSX {
type IntrinsicElements = {
[Tag in keyof TagNameMap]: TagNameMap[Tag] & Base
};
export interface Element extends Base {}
export interface ElementChildrenAttribute {
children: any; // JSX标签中子节点即children的类型
}
}
}
Write a Component, and the child node is a function, that is, render props rendering
function Text({ children }: { children?: (value: number) => JSX.Element }) {
return <text>{children(233)}</text>;
}
function App() {
return (
<view>
<text bindtap={() => console.log("click")} />
<Text>{value => <text>{value}</text>}</Text>
</view>
);
}
If it is a jsx file, you need to add the @babel/plugin-transform-react-jsx plugin to babel and configure pragma(i.e. jsxFactory function) for the createElement function you implement, such as the default React.createElement. But now it's a tsx file, and when ts is compiled to js, you can configure compileOptions in tsconfig.json, and you can specify target, that is, the specific es version, and the module module specification, and so on. Tsx needs to be configured with two options: