moonlight-mod / mappings

WIP mappings for the Discord client, powered by moonmap and LunAST
MIT License
0 stars 0 forks source link

Component Keys #4

Open Cynosphere opened 1 month ago

Cynosphere commented 1 month ago

Cannot import destructure from Components

NotNite commented 1 month ago

I'm not sure this is even possible to solve without just typing everything (which we could but seems jank). This might be a TypeScript bug? Anyways, let me explain the problem for anyone else who was confused by the issue name.


The components type does this:

type CommonComponents = {
  [index: string]: any;
  // other typed components follow
};

This means that you can use typed components such as Text, but ones we don't have typed like Notice still work (they're just any). Without that index signature, you couldn't import Notice here without an error:

// Property 'Notice' does not exist on type 'CommonComponents'.ts(2339)

const { Text, Notice } = require("discord/components/common/index");
// or
const Components = require("discord/components/common/index");
const Notice = Components.Notice;
// or
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
const Notice = Components.Notice;

...but with that index signature, Text will be the typed component, and Notice will be any in all of these examples.

The mappings repo generates the following declare (this is actually wrong for some types with default but it's valid here):

declare module "@moonlight-mod/wp/discord/components/common/index" {
  import { MappedModules } from "@moonlight-mod/mappings";
  const _: MappedModules["discord/components/common/index"];
  export = _;
}

(The _ is just the components type, by the way.)

You would expect the TypeScript compiler to be able to recognize that index signature, but it can't:

// Module '"@moonlight-mod/wp/discord/components/common/index"' has no exported member 'Notice'.ts(2305)

import { Text, Notice } from "@moonlight-mod/wp/discord/components/common/index";

This works, but isn't desirable because it looks funky:

import * as Components from "@moonlight-mod/wp/discord/components/common/index";
const { Notice } = Components;
// or
const Notice = Components.Notice;

Looks like, when resolving imports to destructure, TypeScript doesn't consider the index signature. I'll try and get a reproduction case going and make an issue.