Request for PR: Writing your own index.d.ts
swyxio opened this issue Β· comments
I don't know this one myself.. I would love a good guide.
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 πππ
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!
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
Anyone willing to take this or should I take it? :)
Will take this and propose a PR later in the evening
I'm sorry for delaying this, but I will try my best soon π
take your time, we're all busy :)
Sorry, I can't get to this, any one is welcomed to send a PR
dts-gen is also helpful, as well as this SO answer: https://stackoverflow.com/questions/12687779/how-do-you-produce-a-d-ts-typings-definition-file-from-an-existing-javascript