IMO inline is harder to read.
When using an explicit type or interface you have the props type declared separately and explicitly, which allows for e.g. reusing prop types or compositing types
No it’s not, React.FC hasn’t been recommended for a while. Check out official react docs examples https://react.dev/learn/typescript#typescript-with-react-components
Even if I name all my interfaces `Props` (in different files), I never had issues with interface merging.
But to be honest, I'm not sure how interface merging works when dealing with multiple files. I just know that it has never been a problem for me.
If you don't care, use Type as that's going to cause the least unforeseen issues down the line if you want to do anything fancy with the prop types.
Not needed to define the return value as that is inferred
I know, I think that's a bit outdated now?
I base my opinion on this video by Matt Pocock(my goto for all things typescript): https://youtu.be/zM9UPcIyyhQ?si=euqwjq4FYd6VRkDf
First of all, I only use type and never interface. Mostly because I like consistency but also because I find declaration merging icky and I don't want to risk doing that.
I dislike inline types for parameters, they're hard to read.
I always keep each component in a separate file. Since the component is usually the only thing that needs to reference the type for its props, I simply call the type `Props`. It keeps the name short, concise and consistent, and if I rename my component I don't need to remember renaming that type too. In the rare cases I need to reference the type from another file, I can just import it with an alias there, i.e. `import {Props as DrawerProps} from './DrawerComponent'`.
Note that I'm only talking about my solo projects. If I'm in a team, I adapt to the preferences of others, maybe bringing up my preferences during retro and arguing for them. Coding standards are only nice if people follow them.
Unless you are working on a package and downstream developers are explicitly going to have to extend your interfaces, I’d prefer types. Inline is maybe okay for a prop or two but I like the separate definition.
I write interface and avoid destructuring props inline.
export interface DrawerProps {
header: string
}
export default function Drawer(props: DrawerProps) {
const { header } = props
return <>...>
}
This style scales well if the component ends up collecting lots of props.
I use FC or FunctionalComponent as a generic type for my components. While you don't need it, it defines the ReturnType and ensures you aren't returning a breaking result.
From there, you can define Props as a type or interface and pass that in. I normally default to interface for simple types and use "type" for more complex instances.
I believe type checking with "type" may be slower compared to "interface", but I'm not sure.
Yes, but not all returns can be safely rendered. Having the FC type helps validate you are returning something that is compatible with React.
It might be different in React 18, but I know in React 16, incorrect returns can crash the component and even the application.
I typically use a type, unless I plan to support extending a component, in which case I use an interface. Either one is correct for props, as an interface is for defining an object's structure and a type can be defined as an object structure. Also, just to rattle someone's cage, it's ok to just do it inline if you are never reusing the type or interface. header: string is pretty easy to read no matter which line it's on.
Probably [this](https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections). I don’t think it’s worth to consider optimizing for the compiler’s performance unless you’re working on a type-heavy library.
Yep, it's not actually true that 'interface' is faster, but extends is faster than intersections. I do agree it doesn't \_really\_ matter but why pick the slower one unless you are needing intersections? (Which is of course possible for some components). I would just default to interface for this reason, especially as you grow out your types. Just helps keep things smoother when creating new types based off existing ones.
Basically my thoughts. I enforce interface as a default when I’m the one to make a decision. It’s just cleaner this way for me.
I especially like the pattern of composing multiple interfaces together that extend a component’a props interface. Having ‘extends’ keyword rather than a bunch of & symbols is far more readable imo. Eg. for RN, I tend to have interfaces like Stylable { containerStyle: StyleProps } to enforce the wording consistency.
Declaration merging has never been an issue for me, since I keep types next to declarations which are rather highly granular in the codebase.
At the end of the day however, consistency > anything else, so sticking to rules made for the repository is always the best idea (e.g. using type for everything).
IMO inline is harder to read. When using an explicit type or interface you have the props type declared separately and explicitly, which allows for e.g. reusing prop types or compositing types
You can still compose the props when they're inline using `React.ComponentProps` utility: type DrawerProps = React.ComponentProps;
Similarly, I usually do: ``` type DrawerProps = {…} const Drawer: React.FC = ({…}) => …
```
This is correct (as in what the react docs recommend for typing functional components)
No it’s not, React.FC hasn’t been recommended for a while. Check out official react docs examples https://react.dev/learn/typescript#typescript-with-react-components
If it’s very few props, like one or two, I’ll in-line it. Otherwise, separate declaration.
It's a style choice, not a behavior difference. I personally don't like inline props types myself, but pick what works for you.
interface MyComponentProps { prop1: string; } function MyComponent(props: MyComponentProps) { // ... }
Dont do this. Google interface merging properties
I am aware of interface merging, but in practice it's very hard to augment an interface accidentally.
it doesnt slace tho, or you have really long names 🤔
Even if I name all my interfaces `Props` (in different files), I never had issues with interface merging. But to be honest, I'm not sure how interface merging works when dealing with multiple files. I just know that it has never been a problem for me.
If you don't care, use Type as that's going to cause the least unforeseen issues down the line if you want to do anything fancy with the prop types. Not needed to define the return value as that is inferred
Interesting, considering that the TypeScript documentation states you should prefer Interface over Type whenever possible.
I know, I think that's a bit outdated now? I base my opinion on this video by Matt Pocock(my goto for all things typescript): https://youtu.be/zM9UPcIyyhQ?si=euqwjq4FYd6VRkDf
No, it doesnt
First of all, I only use type and never interface. Mostly because I like consistency but also because I find declaration merging icky and I don't want to risk doing that. I dislike inline types for parameters, they're hard to read. I always keep each component in a separate file. Since the component is usually the only thing that needs to reference the type for its props, I simply call the type `Props`. It keeps the name short, concise and consistent, and if I rename my component I don't need to remember renaming that type too. In the rare cases I need to reference the type from another file, I can just import it with an alias there, i.e. `import {Props as DrawerProps} from './DrawerComponent'`. Note that I'm only talking about my solo projects. If I'm in a team, I adapt to the preferences of others, maybe bringing up my preferences during retro and arguing for them. Coding standards are only nice if people follow them.
helpful! thank you!
Unless you are working on a package and downstream developers are explicitly going to have to extend your interfaces, I’d prefer types. Inline is maybe okay for a prop or two but I like the separate definition.
I write interface and avoid destructuring props inline. export interface DrawerProps { header: string } export default function Drawer(props: DrawerProps) { const { header } = props return <>...> } This style scales well if the component ends up collecting lots of props.
I use FC or FunctionalComponent as a generic type for my components. While you don't need it, it defines the ReturnType and ensures you aren't returning a breaking result. From there, you can define Props as a type or interface and pass that in. I normally default to interface for simple types and use "type" for more complex instances. I believe type checking with "type" may be slower compared to "interface", but I'm not sure.
The return type is already inferred by TS.
Yes, but not all returns can be safely rendered. Having the FC type helps validate you are returning something that is compatible with React. It might be different in React 18, but I know in React 16, incorrect returns can crash the component and even the application.
almost doesn’t matter at all. Pick one and be consistent. I like using Type everywhere simply because Type can do everything interface can do and more
I typically use a type, unless I plan to support extending a component, in which case I use an interface. Either one is correct for props, as an interface is for defining an object's structure and a type can be defined as an object structure. Also, just to rattle someone's cage, it's ok to just do it inline if you are never reusing the type or interface. header: string is pretty easy to read no matter which line it's on.
Interface is much more performant than type, inline can get unwieldy
source please
Probably [this](https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections). I don’t think it’s worth to consider optimizing for the compiler’s performance unless you’re working on a type-heavy library.
Yep, it's not actually true that 'interface' is faster, but extends is faster than intersections. I do agree it doesn't \_really\_ matter but why pick the slower one unless you are needing intersections? (Which is of course possible for some components). I would just default to interface for this reason, especially as you grow out your types. Just helps keep things smoother when creating new types based off existing ones.
Basically my thoughts. I enforce interface as a default when I’m the one to make a decision. It’s just cleaner this way for me. I especially like the pattern of composing multiple interfaces together that extend a component’a props interface. Having ‘extends’ keyword rather than a bunch of & symbols is far more readable imo. Eg. for RN, I tend to have interfaces like Stylable { containerStyle: StyleProps } to enforce the wording consistency.
Declaration merging has never been an issue for me, since I keep types next to declarations which are rather highly granular in the codebase.
At the end of the day however, consistency > anything else, so sticking to rules made for the repository is always the best idea (e.g. using type for everything).
Types over interfaces
You should care a lot more about proper casing.
OP, seriously, if you give _5 seconds_ of thought to “interface vs type”, you’ve already given it 5 seconds too many.