Skip to content

Add TypeScript declaration file - #279

Closed
Swizz wants to merge 3 commits into
hyperapp:masterfrom
Swizz:typing
Closed

Swizz wants to merge 3 commits into
hyperapp:masterfrom
Swizz:typing

Conversation

@Swizz

@Swizz Swizz commented Jul 4, 2017 •

Copy link
Copy Markdown
Contributor

Following #87 : I present you my version of a TypeScript declaration only for the Hyperapp API.

The following define lot of interfaces as fixed one, but make it able to partially use them trough Partial<Interface> (Thanks to @nippur72).
All the interfaces need to be extended in order to be used.

Custom Events support is free by extending the Events interface, but without fixed typing yet.


This declaration file has been tested against the following features with the following implementation.

import { h, app, Actions, Events, Application, emitFunction } from 'hyperapp'

interface State {
  readonly count: number,
  readonly name: string
}

interface ActionsInterface extends Actions<State> {
  inc(state: State): Partial<State>,

  subspace: {
    dec(state: State): Partial<State>
  },

  fail(_state: State, _actions: ActionsInterface, _data: any, emit: emitFunction<string>): string
}

interface EventsInterface extends Partial<Events<State, ActionsInterface>> {
  error(_state: State, _actions: ActionsInterface, error: string): never,

  loaded(): void
}

const emmiter: emitFunction<any> = app<State, ActionsInterface, EventsInterface>({
  state: {
    count: 0,
    name: "Jojo"
  },

  actions: {
    inc: state => ({ count: (state.count || 0) + 1 }),

    subspace: {
      dec: state => ({ count: (state.count || 0) - 1 })
    },

    fail: (_state, _actions, _data, emit) =>
      emit("error", "Fail")
  },

  view: (state: State, actions: ActionsInterface) => (
    <div>
      <h1>{state.name || ''}</h1>
      <h2>{state.count || 0}</h2>
      <div>
        <button onclick={actions.inc}>+</button>
        <button onclick={actions.subspace.dec}>-</button>
        <button onclick={actions.fail}>x</button>
      </div>
    </div>
  ),

  events: {
    error: (_state, _actions, error) => {
      throw error
    },

    loaded: () => {
      console.log('loaded')
    }
  }
})
options value
noImplicitAny true
strictNullChecks true
noUnusedParameters true
jsx react
jsxFactory h

@codecov

codecov Bot commented Jul 4, 2017 •

Copy link
Copy Markdown

Codecov Report

Merging #279 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #279   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           3      3           
  Lines         146    210   +64     
  Branches       44     75   +31     
=====================================
+ Hits          146    210   +64
Impacted Files Coverage Δ
src/app.js 100% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f468dc0...ca4c1df. Read the comment docs.

@jorgebucaran

jorgebucaran commented Jul 4, 2017 •

Copy link
Copy Markdown
Collaborator

Thanks @Swizz! This is looking pretty awesome.

Question: Can't prettier format this file? Try changing the pkg.scripts.format script to accept .ts file extensions too.

Try this:

"format": "prettier --semi false --write 'src/**/*.{js,ts}'",

@Swizz

Swizz commented Jul 4, 2017 •

Copy link
Copy Markdown
Contributor Author

@jbucaran Yes, prettier works with ts files and d.ts files.

I was waiting your comment to use it. Because it produce a more longer file.

@jorgebucaran

jorgebucaran commented Jul 4, 2017 •

Copy link
Copy Markdown
Collaborator

@Swizz Because it produce a more longer file.

No worries.

Change package.json's format script to this:

"format": "prettier --semi false --write 'src/**/*.{js,ts}'",

and run npm run format for rock and roll. 🤘

@Swizz

Swizz commented Jul 4, 2017

Copy link
Copy Markdown
Contributor Author

The declaration file is not under src folder but in the root folder.
And I dont know how to achieve that with glob pattern ^^'

@jorgebucaran

Copy link
Copy Markdown
Collaborator
"format": "prettier --semi false --write 'src/**/*.js' '*.ts'",

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz I tried using the file in a project with vscode and intellisense didn't fire like I expected. Is there any additional work required so that vscode/$EDITOR/etc., picks up this file?

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz What about a typings.json file too?

{
  "name": "hyperapp",
  "main": "src/hyperapp.d.ts"
}

@Swizz

Swizz commented Jul 4, 2017 •

Copy link
Copy Markdown
Contributor Author

@jbucaran From where are you using it ?

As it declared as a module, exported declarations will follow with

import { h, app, Actions, Events, Application, emitFunction } from 'hyperapp'

For a local use, you will need to npm link your current hyperapp repo or explicitly import the declaration file

/// <reference path="..." />

Isnt typings deprecated in favor of package.json ?
https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz For a local use, ... our explicitly import the declaration file.

Sweet! How can I explicitly import the declaration file?

Comment thread hyperapp.d.ts
ActionsInterface extends Actions<State> | undefined
> {
loaded:
| ((

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can remove the extra parentheses, it was for readability purpose but prettier do it as well

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give prettier the last word! :)

@Swizz Swizz Jul 4, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not :/
Cause union types :
(a: number, b: string) => number | string
A function that take a as a number and b as a string and return a number or a string

is not
((a: number, b: string) => number) | string
A function that take a as a number and b as a string and return a number. Or a string

So let's let them here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Swizz So prettier is wrong?

@Swizz Swizz Jul 4, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was right by writing them; prettier was right to keep them ; I was wrong at reading them again to take them as extra parentheses

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omg 😆

@Swizz

Swizz commented Jul 4, 2017

Copy link
Copy Markdown
Contributor Author

Sweet! How can I explicitly import the declaration file?

/// <reference path="./hyperapp.d.ts" />

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz Sorry, but where do I put <reference path="./hyperapp.d.ts" />? I have no clue.

@Swizz

Swizz commented Jul 4, 2017 •

Copy link
Copy Markdown
Contributor Author

Sorry, because it was defined as module, using it in a local environement is pretty tricky

/// <reference path="./hyperapp.d.ts" />

import { h, app, Actions, Events, Application, emitFunction } from 'hyperapp'

But you will not be able to use it directly, because node will look at hyperapp.
Module is for outside works and namespaces for internal uses 😠

That is why I recommend the use of npm link

or something like the following instead of modules

export = HyperApp

declare namespace HyperApp {
  ...
}

Comment thread hyperapp.d.ts
actions?: Actions<State>,
data?: any,
emit?: emitFunction<any>
) => Partial<State> | any)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, following #280 (comment)

An action could return either a Partial<State>, any or void or never ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Swizz An action can return an entire state (the same or a new one), a fragment of the state, a Promise, null or undefined.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Promise that resolve to a State (or fragment) ?

=> Partial<State> | Promise<Partial<State>> | void | never

@jorgebucaran jorgebucaran Jul 4, 2017 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Promise that resolves to any.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something more like ?

=> Partial<State> | Promise<Partial<State> | any> | void | never

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type ActionResult = Partial<State> | Promise<ActionResult> | any | void | null
=> ActionResult 

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is void === undefined?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void is the opposite of any both undefined or null.
But with strictNullChecks enable, it is needed to define null explicitly.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in TypeScript void works a bit differently than other languages (C, Java etc); it's not just "no return value", but it's more like an alias for undefined. For example:

function a(): void {}
let b = a(); // strange, but this is allowed, and it's b === undefined

So I think it's ok to have void and left out undefined from our signature. I would also omit any because it makes the signature useless for type checking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we are back on a circular type reference ?

type ActionResult = Partial<State> | Promise<ActionResult> | void | null

export interface Actions<State> {
    [key: string]:
      | ((
          state?: State,
          actions?: Actions<State>,
          data?: any,
          emit?: emitFunction<any>
        ) => ActionResult)
      | Actions<State>
  }

@Swizz

Swizz commented Jul 4, 2017

Copy link
Copy Markdown
Contributor Author

If you are thinking about it this following implementation is also working as expected

type State = number;

interface ActionsInterface extends Actions<State> {
  inc(count: State): State,
  dec(count: State): State
}
interface ActionsInterface extends Actions<number> {
  inc(count: number): number,
  dec(count: number): number
}

Comment thread hyperapp.d.ts
actions?: Actions<State>,
data?: any,
emit?: emitFunction<any>
) => Partial<State> | any)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be Partial<State> | Promise<Partial<State>> | void

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are on discussion about it above ^^'

@jorgebucaran

jorgebucaran commented Jul 4, 2017 •

Copy link
Copy Markdown
Collaborator

I know @DanielRosenwasser expressed interest in helping out with the typings. Can you help review this PR? 👋😏

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {

@jorgebucaran jorgebucaran Jul 5, 2017 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Swizz Why not declare namespace hyperapp {?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are similar but different. declaring module are more ES6/CommonJS where declaring namespace is more like exposing a global object.
This is why if you export and object you will need to export the namespace too.

export = HyperApp

declare namespace HyperApp {
  ...
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like you need to consider the various consumption cases for hyperapp

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since hyperapp ends up being packaged as a UMD module, should we follow the module.d.ts UMD example from the TypeScript handbook?

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {
export interface VNodeData {
[key: string]: any

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this good? I ask because attributes can only be a string, number, function, null/undefined, an object in the case of key=style.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Less naive VNodeData interface

Here, as you wish, we can be really straight but generics :

export interface VNodeData {
  [key: string]: string | number | Function | null
               | undefined | Object //as everything is object this is like all : `any`
}

Or we can dive into the horrific (like did in @Types/React), add a type to every attrs 👎
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L2101

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Swizz I don't know how to write this file, so I am only asking to learn. Please make the typings in the best way you know. Size doesn't matter.

@Swizz Swizz Jul 5, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Size doesn't matter, but I dont want you to be in charge of a monster. The react types is too too.

Here, I think we can allow the use of any. I dont want to maintain a complete list of HTML attribute, and how about custom ones ? And how about new ones ?
An attribute is nothing more a key and a value, and a value can be everything so any.

@nippur72 Do you agree ?

edit : Preact was on the thoughts to type all the attrs too 😕
https://github.com/developit/preact/blob/master/src/preact.d.ts

Only for JSX. For Vnode they let the same at us

interface VNode {
  nodeName:ComponentConstructor<any, any>|string;
  attributes:{[name:string]:any};
  children:VNode[];
  key:string;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Swizz attribute typing is a cool feature that lets you spot a lot of errors at compile time, so we should attempt to cover it. We don't have to implement it from scratch, we can easily adapt react or preact (their typings are MIT licensed). Custom attributes are not a problem: they do appear in custom elements which in turn are extensions of native HTML elements; their typings should be automatic if the component is written the right way.

The only problem I see is with events when an action is passed as event handler, e.g.

<button onclick={actions.some}></button>

but I think that can be solved by something like EventHanlder | Action

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use the example I have from Picodom. We should absolutely avoid using any and prefer {} when possible.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the JSX types, you could put them in a separate file (e.g. jsx.d.ts) and bring them in here using export * from "./jsx";. Might make ongoing maintenance a little easier since the massive typings of JSX will be separated from the core library typings. Just a thought

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it VNodeData where lifecycle methods and keys would go? Would be nice to demonstrate those here too.

Comment thread hyperapp.d.ts
children: string | VNode | Array<VNode>
}

export type viewFunction<State, Actions> = (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why declare viewFunction's type here? and what is vnodeFunction?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is requested into the Application interface

export interface Application<
    State,
    ActionsInterface extends Actions<State> | undefined,
    EventsInterface extends Partial<Events<State, ActionsInterface>> | undefined
  > extends Partial<Mixin<State, ActionsInterface, EventsInterface>> {
    root: HTMLElement
    view: viewFunction<State, ActionsInterface>
  }

and the render event

 export interface Events<
    State,
    ActionsInterface extends Actions<State> | undefined
  > {
 render:
      | (
          state: State,
          actions: ActionsInterface,
          view: viewFunction<State, ActionsInterface>,
          emit: emitFunction<any>
        ) => viewFunction<State, ActionsInterface>
  }

For vnodeFunction I wanted a way to express a function that return a vnode for h, and I wasnt sure about Component. But as the discution is closed, we can move into now.

export function h(
    tag: string | vnodeFunction,
    data?: VNodeData,
    children?: Array<number | string | VNode>
  ): VNode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, it's better to declare interfaces than types. You can make an interface like,

interface View<S, A> {
     (state: S, actions: A): VNode;
}

@jorgebucaran jorgebucaran mentioned this pull request Jul 16, 2017
@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz How is this coming along? 😄

Do you think you could help me a bit understand what's going on this file? It's really big and I am not
familiar with any of the syntax. 😅

@Swizz

Swizz commented Jul 16, 2017

Copy link
Copy Markdown
Contributor Author

Let me check, what is needed to do right now.

  • We need to conclude about Actions API
type ActionResult = Partial<State> | Promise<ActionResult> | void | null

export interface Actions<State> {
    [key: string]:
      | ((
          state?: State,
          actions?: Actions<State>,
          data?: any,
          emit?: emitFunction<any>
        ) => ActionResult)
      | Actions<State>
}
  • Decide about a naive or a complete VnodeData interface
export interface VNodeData {
    [key: string]: any
}
  • Perform some name polish, like Component instead of vnodeFunction

  • And maybe add some documentations in the .d.ts file


Isnt Typescript Guide a good teacher ? ^^

@Swizz

Swizz commented Jul 17, 2017

Copy link
Copy Markdown
Contributor Author

Can I ask @nippur72 @rbiggs @LucianU and @DanielRosenwasser reviews and feedbacks on it ?

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz Perform some name polish, like Component instead of vnodeFunction

That sounds correct. The term we use in the documentation is Component, so that's what it should be.

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz Actions/Events are no longer passed the emit function, so that argument should be removed too.

@Swizz

Swizz commented Jul 17, 2017

Copy link
Copy Markdown
Contributor Author

@jbucaran You are right, I need to rethink the API regarding recent changes

@pspeter3

Copy link
Copy Markdown
Contributor

Would it be helpful to have another reviewer? I made a PR for Picodom, Preact, and I've done a lot of the type definitions in DefinitelyTyped.

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@pspeter3 Welcome aboard! 👍

@pspeter3 pspeter3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are a few things to think through/improve:

  • How we want to handle various module types
  • How typed JSX and VNodes should be
  • Naming types and generics

I think the last one is the most important. In a lot of ways, the DTS can serve as documentation for the library so good types/names are critical.

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like you need to consider the various consumption cases for hyperapp

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {
export interface VNodeData {
[key: string]: any

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use the example I have from Picodom. We should absolutely avoid using any and prefer {} when possible.

Comment thread hyperapp.d.ts
children: string | VNode | Array<VNode>
}

export type viewFunction<State, Actions> = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, it's better to declare interfaces than types. You can make an interface like,

interface View<S, A> {
     (state: S, actions: A): VNode;
}

Comment thread hyperapp.d.ts
export interface Actions<State> {
[key: string]:
| ((
state?: State,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this is begging for a named interface. TypeScript produces better error messages against named interfaces rather than anonymous types.

@Swizz

Swizz commented Jul 18, 2017

Copy link
Copy Markdown
Contributor Author

@pspeter3 May I ask you to make a PR on my fork ? I am a little bit busy these days. Or I can make you as contributor as well

@jorgebucaran

Copy link
Copy Markdown
Collaborator

/cc @Swizz

@pspeter3 Can you create a new PR with your own implementation?

@pspeter3

Copy link
Copy Markdown
Contributor

Yeah, I can do that.

@andrewiggins andrewiggins left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting this! I was just writing my own until I found this PR.

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since hyperapp ends up being packaged as a UMD module, should we follow the module.d.ts UMD example from the TypeScript handbook?

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {
export interface VNodeData {
[key: string]: any

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the JSX types, you could put them in a separate file (e.g. jsx.d.ts) and bring them in here using export * from "./jsx";. Might make ongoing maintenance a little easier since the massive typings of JSX will be separated from the core library typings. Just a thought

Comment thread hyperapp.d.ts
state: State,
actions: Actions
) => VNode
export type emitFunction<Data> = (event: string, data?: Data) => Data

@andrewiggins andrewiggins Jul 20, 2017 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm would it possible to make the type of the event function stronger by taking the EventInterface as a generic and using the keyof operator. Something like

export type emitFunction<Data, EventInterface> = (event: keyof EventInterface, data: Data) => Data

That should give better intellisense for any emit function that knows the event interface and enforce the event types an app supports.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the EventInterface of emitFunction extend Events?

Comment thread hyperapp.d.ts
state: State
actions: ActionsInterface
events: EventsInterface
mixins: Array<Partial<Mixin<State, ActionsInterface, EventsInterface>>>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the doc, does this need to be an array of functions that return Partial<Mixin>'s?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your Mixins can contains only events or actions for example. You do not need to define all the Mixin props. So, Partial<Mixin> ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. Partial is definitely needed. I was suggesting, should the type of the mixins property be:

mixins: Array<() => Partial<Mixin<State, ActionsInterface, EventsInterface>>>

Unless I'm misunderstanding the API doc

Comment thread hyperapp.d.ts
@@ -0,0 +1,149 @@
declare module "hyperapp" {
export interface VNodeData {
[key: string]: any

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it VNodeData where lifecycle methods and keys would go? Would be nice to demonstrate those here too.

Comment thread hyperapp.d.ts
export type emitFunction<Data> = (event: string, data?: Data) => Data
export type vnodeFunction = (
props: VNodeData,
children: string | VNode | Array<VNode>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a type for the Stateless Components doc? If I'm reading the code correctly, the last line in h.js (tag(data, children)) seems to say the children type would always be an array:

children: Array<VNode | string>

@Swizz

Swizz commented Jul 21, 2017

Copy link
Copy Markdown
Contributor Author

We reached a lot of comments here.
And I thought alot about it. How guys are you regarding closing this one an starting a fresh new one ?
Step by step, Together. We make an attempt to build the strongest one an discuss about it after. It will be more plesant and eficient to build it together.


Would it be possible to create something simpler first?
You know like skateboard -> bicycle -> bike -> car -> bus -> tractor -> boeing 777 -> tesla self-landing rocket

@jbucaran - Slack

@jorgebucaran

Copy link
Copy Markdown
Collaborator

@Swizz Sounds good to me! 👍

@andrewiggins

Copy link
Copy Markdown

Happy to help out

@Swizz Swizz mentioned this pull request Jul 21, 2017
4 tasks done
@Swizz

Swizz commented Jul 21, 2017

Copy link
Copy Markdown
Contributor Author

Closed in favor of #311

@Swizz Swizz closed this Jul 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants