typescript-cheatsheets / react

Cheatsheets for experienced React developers getting started with TypeScript

Home Page:https://react-typescript-cheatsheet.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

handled by @arvindcheenu :) #254