skip to Main Content

I created a project with vite v5 by using the react-ts template.

While running the app with: pnpm dev, the following error appears:

App.tsx:9 Uncaught ReferenceError: CharacterConnectionStatus is not defined
    at App.tsx:9:22

My App.tsx file looks like this:

const character: Character = {
  id: "1",
  username: "john_doe",
  firstName: "John",
  lastName: "Doe",
  birthday: "1990-01-01",
  description: "A description of John Doe.",
  avatarURI: "https://placehold.co/400x400",
  connection_status: CharacterConnectionStatus.ONLINE,
};

function App() {
  return (
    <div
      id="app"
      className="h-screen w-screen bg-base-100 text-accent-content antialiased"
    >
      <div className="container mx-auto p-6">{JSON.stringify(character)}</div>
    </div>
  );
}

export default App;

I have a src/types/index.d.ts file that contains the Character interface as well as the CharacterConnectionStatus enum:

// Enums

enum CharacterConnectionStatus {
  ONLINE = "online",
  OFFLINE = "offline",
  AWAY = "away",
}

// Interfaces

interface Character {
  id: string;
  username: string;
  firstName: string;
  lastName: string;
  birthday: string;
  description: string;
  avatarURI: string;
  connection_status: CharacterConnectionStatus;
}

The code works just fine if I set the connection_status field as optional inside the interface:

interface Character {
  // all the other fields
  connection_status?: CharacterConnectionStatus;
}

In order to create the object with no connection_status field on my App component:

const character: Character = {
  id: "1",
  username: "john_doe",
  firstName: "John",
  lastName: "Doe",
  birthday: "1990-01-01",
  description: "A description of John Doe.",
  avatarURI: "https://placehold.co/400x400",
};

Which allows me to know that the project is capable of resolving the Character interface, but not the enum, but both of them are in the exact same file.

In order for the index.d.ts to work, I added the following code to my tsconfig.json file:

{
  "compilerOptions": {
    /* a bunch of config */
    "declaration": true,
    "declarationDir": "/src/types"
  }
}

Is there any visible error on this approach for the server not to resolve the CharacterConnectionStatus enum?

Thanks in advance.

2

Answers


  1. You may not want to use enums in your ts application. Read more on here

    Rename src/types/index.d.ts to src/types/index.ts

    Make sure you are exporting CharacterConnectionStatus and Character as well.

    export const CHARACTER_CONNECTION_STATUS = {
      ONLINE: "online",
      OFFLINE: "offline",
      AWAY: "away",
    } as const;
    
    type CharacterConnectionStatus = keyof typeof CHARACTER_CONNECTION_STATUS;
    
    
    export interface Character {
      id: string;
      username: string;
      firstName: string;
      lastName: string;
      birthday: string;
      description: string;
      avatarURI: string;
      connection_status: CharacterConnectionStatus;
    }
    
    

    Make sure to import CHARACTER_CONNECTION_STATUS and Character in App.tsx

    const character: Character = {
      id: "1",
      username: "john_doe",
      firstName: "John",
      lastName: "Doe",
      birthday: "1990-01-01",
      description: "A description of John Doe.",
      avatarURI: "https://placehold.co/400x400",
      connection_status: CHARACTER_CONNECTION_STATUS.ONLINE,
    };
    
    
    Login or Signup to reply.
  2. You cannot declare enums in a .d.ts file, since it will have a compiled output while interfaces and types will not.

    The closest you can have in a .d.ts file is a type that restricts string constants, like:

    type CharacterConnectionStatus = 'ONLINE' | 'OFFLINE' | 'AWAY';
    

    This does restrict the possible values, but you cannot call them as constants like you could with enums. If you do want to keep using constants, then you should export those types from a .ts file and import them whenever you need them.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search