Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for PR: Writing your own index.d.ts #8

Closed
swyxio opened this issue Jun 3, 2018 · 10 comments
Closed

Request for PR: Writing your own index.d.ts #8

swyxio opened this issue Jun 3, 2018 · 10 comments

Comments

@swyxio
Copy link
Collaborator

swyxio commented Jun 3, 2018

I don't know this one myself.. I would love a good guide.

@m8r1x
Copy link

m8r1x commented Jun 3, 2018

Not sure if it's of any help but personally I've relied on reactstrap and react-bootstrap typings for guidance. I prefer reactstrap approach 🙂

Example

// USAGE: <Button type="type" label="label" /> => <button type="type">label</button>

import * as React from "react";

//  tslint rule - all interface types must start with `I` (disable if needed)
interface IButtonProps<T> extends React.HTMLProps<T> {
  label?: string;
  type?: string;
};
/* 
 *
 * <T> can be any HTML* interface but using the equivalent of the rendered html element is recommended.
 * <li> => HTMLLIElement, <div> => HTMLDivElement e.t.c
 *
 * With vscode you get the added benefit of auto-suggestion for <T>.
 * Go no try it - type `HTML` in a js/ts file and see what happens :)
 *
 * If you navigate to the interface definition of any HTML* interface,
 * you'll find some html attributes already defined.
 * This, together with extending `React.HTMLProps`, saves you the trouble of
 * redefining html attributes like type for <button>, href for <a>, size, width e.t.c
 *
 * But don't get too drunk on DRY. I personally don't mind repeating them as I find
 * that it provides better developer experience making it easier to deprecate/maintain props
 *
 * Some html tags mostly html5 tags like aside, article e.t.c don't have HTML* interfaces defined,
 * so for such maybe use the generic HTMLElement interface instead
 *
 * Sometimes If you try changing some props to required(by omitting the `?` from `?:`),
 * ts complains that you're incorrectly extending one of the interfaces,
 * most likely `React.HTMLProps`.
*/

// WORKAROUNDS FOR ABOVE ISSUE

//a. Override the prop twice
interface IButtonProps<T> extends React.HTMLProps<T> {
  label?: string;
  type: any; // now this is required but we don't just want `any` type 
};

// so we make props an interface
export interface ButtonProps extends IButtonProps<HTMLButtonElement> {
  type: string; // and redefine it here again
};

//b. exclude properties from the type and define them yourself
// Eventually you should be able to use
interface IButtonProps<T> extends Omit<React.HTMLProps<T>, "prop"> {
  [prop]: type;
}
// see links below for Omit reference

// If all is well
export type ButtonProps = IButtonProps<HTMLButtonElement>;

/*
 * Not  entirely sure if there's a different approach for stateless functional component but,
 * At the time of writing reactstrap uses classes for everything.
 * Compare e.g.  reactstrap Col and it's type definition see links below
 * 
*/
declare class Button extends React.Component<ButtonProps> { }; 

export default Button;

// Try playing around with namespaces too!

Hopefully that sheds some light on the subject.

DISCLAIMER: I am not a typescript god/guru 😄. All things above are based on research and experimentation. Any corrections regarding this approach are totally welcome.🙂

Omit StackOverflow reference
Reactstrap Col definition
Reactstrap Col type definition

Thanks for this awesome repo 🎉🎉🎉

@tsiq-swyx
Copy link
Contributor

thanks.. yeah well I will just put in a link to this issue and hope people jump in haha. its ridiculous this stuff isn't documented, companies use this for production!

@ghost
Copy link

ghost commented Jun 3, 2018

This is my example: https://github.com/Attrash-Islam/infinite-autocomplete/blob/master/infinite-autocomplete.d.ts

I export all the needed public functions that the developer work with and with adding this file into "typings" entry in the package.json file

@ghost
Copy link

ghost commented Jun 4, 2018

Anyone willing to take this or should I take it? :)

@ghost
Copy link

ghost commented Jun 5, 2018

Will take this and propose a PR later in the evening

@ghost
Copy link

ghost commented Jun 19, 2018

I'm sorry for delaying this, but I will try my best soon 🙏

@tsiq-swyx
Copy link
Contributor

take your time, we're all busy :)

@ghost
Copy link

ghost commented Jun 25, 2018

Sorry, I can't get to this, any one is welcomed to send a PR

@swyxio
Copy link
Collaborator Author

swyxio commented Jan 27, 2019

@swyxio
Copy link
Collaborator Author

swyxio commented Aug 20, 2020

handled by @arvindcheenu :) #254

@swyxio swyxio closed this as completed Aug 20, 2020
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

No branches or pull requests

3 participants