Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] ImportType node children do not transform #150

Closed
RobinBertilsson opened this issue Jan 20, 2022 · 5 comments
Closed

[Bug] ImportType node children do not transform #150

RobinBertilsson opened this issue Jan 20, 2022 · 5 comments
Labels
Bug Something isn't working

Comments

@RobinBertilsson
Copy link

RobinBertilsson commented Jan 20, 2022

Background
I'm building a React Component Library, and some components are nested, eg. <Form.Button /> & <Form.Input />, but it also has a root element, named <Form />.

Issue
If you take a look at the example repository (provided down below), especially the ./dist/components/form/form.d.ts file. You'll see that it exports a const named Form which is of type FunctionComponent, but it also have to other properties, Button & Input.

The Button property is fine, but the Input property isn't correct since it still imports the Input component from the following path: ~/components/form/input.

The source code for Form.tsx looks like the following

import { Button } from '~/components/form/button'
import { Input } from '~/components/form/input'
import { FunctionComponent } from 'react'

const FormRoot: FunctionComponent = () => (
  <div>MenuRoot</div>
)

export const Form = Object.assign(FormRoot, {
  Button,
  Input
})

Actual output of form.d.ts

import { FunctionComponent } from 'react';
export declare const Form: FunctionComponent<{}> & {
    Button: FunctionComponent<{}>;
    Input: import("react").ForwardRefExoticComponent<import("~/components/form/input").InputProps & import("react").RefAttributes<HTMLInputElement>>;
};

Expected output of form.d.ts

import { FunctionComponent } from 'react';
export declare const Form: FunctionComponent<{}> & {
    Button: FunctionComponent<{}>;
    Input: import("react").ForwardRefExoticComponent<import("../../components/form/input").InputProps & import("react").RefAttributes<HTMLInputElement>>;
};

Example Repository
https://github.com/RobinBertilsson/ts-transform-paths-nested-issue

All help appreciated ❤️


Maintainers Note

This is likely because the child nodes are not visited with the transformer

@RobinBertilsson
Copy link
Author

Update

Since it's trying to look for InputProps inside ~/components/form/input i tried refactor it into a different file, so it wouldn't have to reference itself, and that worked!

@nonara
Copy link
Collaborator

nonara commented Jan 31, 2022

Thanks for the report! I will look into this. This is an interesting one. I think it brings a valid issue to light.

I don't believe that we visit the children of an import call, but I'll have to look into this to confirm.

Can you show me the code you switched it to that does work?

@RobinBertilsson
Copy link
Author

Hi @nonara, sure! So, in the example repository, we have a input.tsxinside ./components/form, which looks like the following

import { forwardRef, Ref } from 'react';

export interface InputProps {
  innerRef?: Ref<HTMLInputElement>
}

const InputElement = ({ innerRef }: InputProps) => (
  <input type="text" ref={innerRef} />
)

export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(props, ref) {
  return (
    <InputElement innerRef={ref} {...props} />
  )
})

But when i instead extract the InputProps to a different file, eg InputProps.ts, and just reference it from within input.tsx, it works... Eg.

import { InputProps } from '~/models/InputProps' // <-- Changed
import { forwardRef, Ref } from 'react'

const InputElement = ({ innerRef }: InputProps) => (
  <input type="text" ref={innerRef} />
)

export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(props, ref) {
  return (
    <InputElement innerRef={ref} {...props} />
  )
})

@evanpurkhiser
Copy link

I'm also seeing this problem in some of my compiled .d files

export declare const responseTransform: {
    readonly 16384: (args: Field[]) => {
        itemsAvailable: number;
    };
    readonly 16387: (_args: Field[]) => null;
    readonly 16385: (_args: Field[]) => null;
    readonly 16897: (_args: Field[]) => null;
    readonly 16641: (args: Field[]) => import("./item").Item<import("src/remotedb/message/item").ItemType.Path> | import("./item").Item<import("src/remotedb/message/item").ItemType.Folder> | import("./item").Item<import("src/remotedb/message/item").ItemType.AlbumTitle> | import("./item").Item<import("src/remotedb/message/item").ItemType.Disc> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitle> | import("./item").Item<import("src/remotedb/message/item").ItemType.Genre> | import("./item").Item<import("src/remotedb/message/item").ItemType.Artist> | import("./item").Item<import("src/remotedb/message/item").ItemType.Playlist> | import("./item").Item<import("src/remotedb/message/item").ItemType.Rating> | import("./item").Item<import("src/remotedb/message/item").ItemType.Duration> | import("./item").Item<import("src/remotedb/message/item").ItemType.Tempo> | import("./item").Item<import("src/remotedb/message/item").ItemType.Label> | import("./item").Item<import("src/remotedb/message/item").ItemType.Key> | import("./item").Item<import("src/remotedb/message/item").ItemType.BitRate> | import("./item").Item<import("src/remotedb/message/item").ItemType.Year> | import("./item").Item<import("src/remotedb/message/item").ItemType.Comment> | import("./item").Item<import("src/remotedb/message/item").ItemType.HistoryPlaylist> | import("./item").Item<import("src/remotedb/message/item").ItemType.OrigianlArtist> | import("./item").Item<import("src/remotedb/message/item").ItemType.Remixer> | import("./item").Item<import("src/remotedb/message/item").ItemType.DateAdded> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorNone> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorPink> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorRed> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorOrange> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorYellow> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorGreen> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorAqua> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorBlue> | import("./item").Item<import("src/remotedb/message/item").ItemType.ColorPurple> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuGenre> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuArtist> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuAlbum> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuTrack> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuPlaylist> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuBPM> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuRating> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuYear> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuRemixer> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuLabel> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuOriginal> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuKey> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuColor> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuFolder> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuSearch> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuTime> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuBit> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuFilename> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuHistory> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuAll> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleAlbum> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleGenre> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleArtist> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleRating> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleTime> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleBPM> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleLabel> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleKey> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleBitRate> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleColor> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleComment> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleOriginalArtist> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleRemixer> | import("./item").Item<import("src/remotedb/message/item").ItemType.TrackTitleDJPlayCount> | import("./item").Item<import("src/remotedb/message/item").ItemType.MenuTrackTitleDateAdded>;
    readonly 16386: (args: Field[]) => Buffer;
    readonly 17922: (args: Field[]) => BeatGrid;
    readonly 18178: (args: Field[]) => CueAndLoop[];
    readonly 17410: (args: Field[]) => WaveformPreview;
    readonly 18946: (args: Field[]) => WaveformDetailed;
    readonly 20226: (args: Field[]) => WaveformHD;
    readonly 19970: (args: Field[]) => CueAndLoop[];
};

https://github.com/EvanPurkhiser/prolink-connect/blob/0166963896bbfbd9fa22581ac0d4cdc9b5f61204/src/remotedb/message/response.ts#L194

Here fieldsToItem is imported from item. It seems to struggle because it's passing in a template argument here https://github.com/EvanPurkhiser/prolink-connect/blob/0166963896bbfbd9fa22581ac0d4cdc9b5f61204/src/remotedb/message/item.ts#L211-L213

@nonara nonara added Bug Something isn't working and removed Needs Investigation labels Oct 20, 2022
@nonara nonara changed the title Paths not transformed if surrounded by react's forwardRef [Bug] ImportType node children do not transform Oct 20, 2022
@nonara nonara closed this as completed in 70871d2 Oct 20, 2022
@nonara
Copy link
Collaborator

nonara commented Oct 20, 2022

Fixed in v3.4.1!

Thanks for catching this one!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants