I have been using typescript in my projects for a month and there're some doubts that I'm struggling with.
Is there a pattern/recommended way to organize types in project architecture?
Let's suppose we have a context with the following interfaces:
export type ToastMessageType = 'info' | 'success' | 'error';
export interface ToastMessageData {
id: string;
title: string;
description: string;
type: ToastMessageType;
}
export interface ToastsStateContextData {
messages: ToastMessageData[];
}
export interface ToastsDispatchContextData {
addToast: (message: Omit<ToastMessageData, 'id'>) => void;
removeToast: (id: string) => void;
}
And there's another component called ToastMessage
that receives a message
prop and has the type of ToastMessageData
:
interface ToastMessageProps {
message: ToastMessageData;
style: React.CSSProperties;
}
const ToastMessage: React.FC<ToastMessageProps> = ({ message, style }) => {
I fell that it is weird to import an interface from a context inside of a component, so there's something wrong going on.
What do you guys recommend?
Project Structure In a TypeScript project, it's best to have separate source and distributable files. TypeScript ( . ts ) files live in your src folder and after compilation are output as JavaScript ( . js ) in the dist folder.
One of the main advantages of using TypeScript in a React application is that the compiler (and the IDE, if configured correctly) can validate all of the necessary properties provided to a component. It can also check that they have the correct type.
Generally, if the type alias/interface is specific only for the component, it is alright to write it within the same .tsx
file, as you can consider them to be used "locally" for that component.
However, there can be scenarios when you need to reuse that type alias/interface across other components, or other helper files (For instance, the interface from component A extends the interface from component B). For this, it will be better to store the type alias/interface in a separate file. For instance, you could have a shared directly that houses all the common type aliases/interfaces that are to be exported.
- pages
- ComponentA
- ComponentB
- shared
- interfaces
- messages.interface.ts
- geo.interface.ts
// etc
- services
- helper
// etc
The main advantage of doing so, is that you will be able to prevent the risk of cyclic dependencies, especially when you find out that you are writing code whereby multiple components are exporting and importing stuff from each other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With