ts-interface-builder icon indicating copy to clipboard operation
ts-interface-builder copied to clipboard

Possibility to support "Node IndexedAccessType"

Open xzilja opened this issue 3 years ago • 2 comments

export interface ICharacter {
  id: string;
  username: string;
}

export interface ICreateCharacterArguments {
  username: ICharacter['username'];
};

Currently generating from this file fails with following error Error: Node IndexedAccessType not supported by ts-interface-builder: ICharacter['username']

EDIT: Additional context on this type https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html

xzilja avatar Mar 25 '21 15:03 xzilja

I'm trying to play around with this and essentially tweaked

https://github.com/gristlabs/ts-interface-builder/blob/5c0fa5b393743b18e0a2987dd7126114838f57e4/lib/index.ts#L96-L97

and added additional case at the end

case ts.SyntaxKind.IndexedAccessType:
         return this._compileIndexSignatureDeclaration(node);

But I am then getting stuck here https://github.com/gristlabs/ts-interface-builder/blob/5c0fa5b393743b18e0a2987dd7126114838f57e4/lib/index.ts#L261

I am not sure where this type needs to be set / added at the moment

xzilja avatar Mar 26 '21 07:03 xzilja

IndexedAccessType is a different kind of node than an IndexSignatureDeclaration. So your case should look like

case ts.SyntaxKind.IndexedAccessType:
   return this._compileIndexedAccessType(node as ts.IndexedAccessTypeNode);

You can learn more about that node type by finding it in the TypeScript source code: TypeScript/src/compiler/types.ts.

As for what code ts-interface-builder should actually emit in this case, that's the hard part. I think it requires a new kind of node that ts-interface-checker would have to support, maybe something like t.typeProp("ICharacter", "username"). But TypeScript is actually more flexible -- https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html -- so to support it better, it perhaps should be t.typeProp("ICharacter", t.lit("username")). And it would need to be implemented on the ts-interface-checker side.

There might be other ways of doing it -- e.g. if ICharacter["username"] is known to be string, just to emit "string". There is enough inference in TypeScript compiler that it's probably possible, at least in some cases, but probably not in general.

dsagal avatar Mar 26 '21 14:03 dsagal