Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/core/WidgetBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ export class WidgetBase<P = WidgetProperties, C extends DNode = DNode> implement
*/
static _type = WIDGET_BASE_TYPE;

/**
* property specifically for typing when using tsx
*/
/* tslint:disable-next-line:variable-name */
public __properties__!: P & WidgetProperties & { __children__?: DNode[] | DNode };

/**
* children array
*/
Expand Down
9 changes: 7 additions & 2 deletions src/core/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ export interface MiddlewareResultFactory<Props, Children, Middleware, ReturnValu
export interface DefaultChildrenWNodeFactory<W extends WNodeFactoryTypes> {
(properties: W['properties'], children?: W['children'] extends any[] ? W['children'] : [W['children']]): WNode<W>;
new (): {
properties: W['properties'] & { __children__?: DNode | DNode[] };
__properties__: W['properties'] & { __children__?: DNode | DNode[] };
};
properties: W['properties'];
children: W['children'];
Expand All @@ -425,7 +425,7 @@ export interface WNodeFactory<W extends WNodeFactoryTypes> {
: W['children'] extends any[] ? W['children'] : [W['children']]
): WNode<W>;
new (): {
properties: W['properties'] & { __children__: W['children'] };
__properties__: W['properties'] & { __children__: W['children'] };
};
properties: W['properties'];
children: W['children'];
Expand Down Expand Up @@ -530,6 +530,11 @@ export interface WidgetBaseInterface<P = WidgetProperties, C extends DNode = DNo
* Main internal function for dealing with widget rendering
*/
__render__(): RenderResult;

/**
* property used for typing with tsx
*/
__properties__: P & { __children__?: DNode[] | DNode };
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/core/vdom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ declare global {
namespace JSX {
type Element = WNode;
interface ElementAttributesProperty {
properties: {};
__properties__: {};
}
interface IntrinsicElements {
[key: string]: VNodeProperties;
Expand Down Expand Up @@ -437,7 +437,8 @@ export const REGISTRY_ITEM = '__registry_item';

export class FromRegistry<P> {
static type = REGISTRY_ITEM;
properties: P = {} as P;
/* tslint:disable-next-line:variable-name */
__properties__: P = {} as P;
name: string | undefined;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/core/unit/tsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ registerSuite('tsx', {
const registryWrapper = new RegistryWrapper();
assert.strictEqual(registryWrapper.name, 'tag');
// These will always be undefined but show the type inference of properties.
registryWrapper.properties = {};
assert.isUndefined(registryWrapper.properties.key);
registryWrapper.__properties__ = {};
assert.isUndefined(registryWrapper.__properties__.key);
},
tsx: {
'tsx generate a VNode'() {
Expand Down
13 changes: 12 additions & 1 deletion tests/core/unit/tsxIntegration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ registerSuite('tsx integration', {
const firstQuxRender = qux.__render__() as WNode;
assert.strictEqual(firstQuxRender.widgetConstructor, 'LazyFoo');
},
'typed children'() {
'function-based typed children'() {
const factory = create().children<{ left: () => RenderResult; right: () => RenderResult }>();
const Foo = factory(function Foo({ children }) {
const [c] = children();
Expand All @@ -72,5 +72,16 @@ registerSuite('tsx integration', {
// <Foo>{{ left: () => 'left'}}</Foo>;
// <Foo>{{ right: () => 'right'}}</Foo>;
// <Foo><div></div></Foo>;
},
'class-based widget with children'() {
class Foo extends WidgetBase<{ foo: string }> {
render() {
return this.children;
}
}

<Foo key="" foo="">
<div />
</Foo>;
}
});