reactjs - typed react - props som `type` eller en `interface`


Jeg har React-kode

export default class MyComponent extends Component<Props,State>

Spørsmålet er, skriver jeg props som en type eller en interface?

type Props = {
    isActive: Boolean,
    onClick: Function
}

eller

interface Props {
    isActive: Boolean,
    onClick: Function
}

Også, hva er forskjellen når jeg ikke bruker TypeScript, men klassisk Webpack+Babel-oppsett?

Eller, spiller det egentlig så stor rolle for meg?

Svar #1

Det er 2020 nå, og jeg vil foretrekke type i nesten alle tilfeller med React-props (generell type vs interface-innlegg er her). Vanlige tilfeller som bare kan uttrykkes med typealias:

// given some props from another comp that are to be altered
type ExternalProps = { a: string; b: { c: number } };

type Props_IndexType = ExternalProps["b"]; // { c: number; }
type Props_MappedType = { [K in keyof ExternalProps]: number }; // { a: number; b: number; }
type Props_DiscriminatedUnionType = { tag: "tag1"; foo: string } | { tag: "tag2"; foo: boolean}
type Props_typeOf = { foo: string } & typeof defaultProps; // see class comp example

// conditional types - ok, this one is a bit contrived, but you get the point
type Props_ConditionalType<T> = T extends true ? { a: string } : { b: number };
const Comp = <T extends {}>(props: Props_ConditionalType<T>) =>
  <div>{"a" in props && (props as any).a}</div>
render(<Comp<true> a="foo" />, document.getElementById("root"));

Eksempel på klassekomponent for illustrasjon (OP nevner dem, men de ovennevnte tilfellene gjelder også for Hooks):

// cannot do that with interfaces
type Props = ({ tag: "tag1"; foo: string } | { tag: "tag2"; foo: boolean }) &
  typeof defaultProps;
type State = typeof initState;

const defaultProps = { a: "A" };
const initState = { c: "C" };

class App extends React.Component<Props, State> {
  static readonly defaultProps = defaultProps;
  state = initState;

  render() { ... }
}

render(<App tag="tag1" foo="foo" />, document.getElementById("root"));

De eneste tilfellene jeg ville vurdert grensesnitt:

  • Du gjør deklarasjonsfletting av proptype-typer i det globale omfanget (uvanlig i dag)
  • Du vil skjule implementeringsdetaljer for typen, ettersom grensesnitt oppretter et nytt navn som brukes i feilmeldinger, IDE-typeinformasjon osv. (dokumentasjon)

Svar #2

Grensesnitt er litt mer kraftfulle enn den tilsvarende typedeklarasjonen, men for et sett med React-egenskaper spiller det sannsynligvis ingen rolle. Du kan lese om forskjellene mellom typer og grensesnitt i dette spørsmålet.

Siden du sannsynligvis ikke kommer til å utvide det grensesnittet eller forsterke det andre steder, er det trolig greit å bruke enten. Men jeg vil si at et grensesnitt generelt foretrekkes for å definere objekttyper siden de er litt mer fleksible.

Relaterte artikler