Skip to content

$$Generics fail when using an interface/type defined in instance script #1335

@dummdidumm

Description

@dummdidumm

The following doesn't work:

interface NestedObject {
    1: {
        a: boolean;
        b: boolean;
    };
    2: {
        x: number;
        y: number;
    };
}

const dummy: NestedObject = {
    1: {
        a: true,
        b: false,
    },
    2: {
        x: 1,
        y: 2,
    },
};

type A = $$Generic<keyof NestedObject>;
type B = $$Generic<keyof NestedObject[A]>;

export let outer: A;
export let inner: B;

const fail = dummy[outer][inner];

It fails with this error:

let outer: A extends string | number | symbol
Type 'A' cannot be used to index type 'NestedObject'. ts(2536)

Originally posted by @mdorda in #442 (comment)

Reason is that the transformation looks roughly like this:

function render<A extends keyof NestedObject, B extends keyof NestedObject[A]>() {
  // ..
  interface NestedObject { 
    // ..
  }
  // ..
}

The problem is that NestedObject is referenced in the function definition while being in the function itself, so the function generics reference something that isn't defined yet.

A possible solution would be to move them out of the function similarly to what we do with imports already. This came up previously in #1126 where @jasonlyu123 rightfully pointed out that it's not guaranteed that the interface does not reference anything within the function. So for example this const a = 'b'; interface Wtf { [a]: boolean } is valid TypeScript. I'm not sure what the best way forward here is. We could maybe only move types/interfaces into the module script if they are referenced inside a generic.

The workaround for the issue right now would be to move NestedObject into a <script context="module"> tag.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedFixed in master branch. Pending production release.bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions