Skip to content

Commit

Permalink
finish it wrongly
Browse files Browse the repository at this point in the history
  • Loading branch information
cronning9 committed Nov 3, 2019
1 parent d69f559 commit 6e36c06
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 20 deletions.
33 changes: 20 additions & 13 deletions index.ts
Expand Up @@ -3,14 +3,13 @@ import JSXElement, { JSXChildren } from './lib/JSXElement';

export interface IntrinsicElementAttributes {
[key: string]: string | boolean | number;
// banana: string;
}

export interface Component<P = undefined> {
(props: P): JSXElement
export interface Component<P = any> {
(props: P): JSXElement<P>
}

type Identifier = string | Component<unknown>;
type Identifier = string | Component;

/**
* When reading JSX input, the properly-configured TypeScript compiler
Expand All @@ -22,27 +21,35 @@ function run<P extends object>(
identifier: Component<P>,
props: P | null,
...children: JSXChildren
): JSXElement;
): JSXElement<P>;
function run(
identifier: string,
props: IntrinsicElementAttributes | null,
...children: JSXChildren
): JSXElement;
function run<P = undefined>(
): JSXElement<IntrinsicElementAttributes>;
function run<P>(
identifier: Identifier,
props: P | IntrinsicElementAttributes | null,
...children: JSXChildren
): JSXElement {
): JSXElement<P | IntrinsicElementAttributes> {
// check for users who don't use TypeScript
if (!identifierIsString(identifier) && !identifierIsComponent(identifier)) {
throw new InvalidElementError(`Identifier ${identifier} must be a string or a function component`);
}
if (identifierIsString(identifier) && !IntrinsicElements.includes(identifier)) {
throw new InvalidElementError(`${identifier} is not a valid JSX element.`);
}

if (identifierIsComponent<P>(identifier)) {
const element = identifier(props);
return new JSXElement(element, props, ...children);
// TODO: figure out hwo to narrow down to P or IntrinsiceElementAttributes without casting
const element = identifier(props as P);
return new JSXElement(element, props as P, ...children);
}

return new JSXElement(identifier, props, ...children);
return new JSXElement(
identifier as string,
props as IntrinsicElementAttributes,
...children
);
}

function identifierIsString(identifier: Identifier): identifier is string {
Expand All @@ -51,7 +58,7 @@ function identifierIsString(identifier: Identifier): identifier is string {

function identifierIsComponent<P>(identifier: string | Component<P>): identifier is Component<P> {
const argsAreCorrect = (id: Component<P>) => id.arguments.length === 1 || id.arguments.length === 0;
if (!(typeof identifier === 'function') || !argsAreCorrect(identifier)) {
if (typeof identifier !== 'function' || !argsAreCorrect(identifier)) {
return false;
}

Expand Down
14 changes: 7 additions & 7 deletions lib/JSXElement.ts
@@ -1,16 +1,16 @@
import { ComponentProps } from "../index";
import { IntrinsicElementAttributes } from "..";

export type JSXChildren = (string | number | boolean | JSXElement | null)[];
export type JSXChildren = (string | number | boolean | JSXElement<unknown> | null)[];

/**
* The main type of output generated by JSXEngine.run.
*/
export default class JSXElement {
public type: string | JSXElement;
public props: ComponentProps | null;
export default class JSXElement<P> {
public type: string | JSXElement<P>;
public props: P | null;
public children: JSXChildren;

constructor(type: string | JSXElement, props: ComponentProps | null, ...children: JSXChildren) {
constructor(type: string | JSXElement<P>, props: P | null, ...children: JSXChildren) {
this.type = type;
this.props = props;
this.children = children;
Expand Down Expand Up @@ -39,7 +39,7 @@ export default class JSXElement {
}
}

function childrenAreElements(children: JSXChildren): children is JSXElement[] {
function childrenAreElements<P>(children: JSXChildren): children is JSXElement<P>[] {
for (const child of children) {
if (!(child instanceof JSXElement)) {
return false;
Expand Down

0 comments on commit 6e36c06

Please sign in to comment.