ts2fable icon indicating copy to clipboard operation
ts2fable copied to clipboard

[WIP] Fix importing generic types

Open 0x53A opened this issue 6 years ago • 5 comments

If I have two files where I export and import a generic type

declare type IGeneric<T> = { value: T };
export { IGeneric }

and

import { IGeneric } from './#xxx-generic-aliases.2';

type IGenericAlias<T> = IGeneric<T>;

declare function f(a: IGeneric<number>, b: IGenericAlias<number>);

export { IGeneric, IGenericAlias, f };

then it currently generates invalid F# code.

0x53A avatar Oct 03 '19 14:10 0x53A

I was following https://stackoverflow.com/questions/50526710/typescript-compiler-api-get-type-of-imported-names for how to get the type of the imported object.

(tl;dr:

let symbol = checker.getSymbolAtLocation(imp.name)
let type = checker.getDeclaredTypeOfSymbol(symbol);

The change in CompilerHost was neccessary because without it it would always return undefined. With this change it returns a valid type.

0x53A avatar Oct 03 '19 14:10 0x53A

This actually fixes two things:

  • the mentioned issue when importing generics
  • default exports were not imported

see https://github.com/microsoft/TypeScript/blob/9a62db2b5c5a305139d18f5f25c725f0779493cd/src/compiler/types.ts#L1807-L1817

If I did import d, { a } from 'x' then only a was imported, d was ignored. Now with this change, both should be correctly imported.

0x53A avatar Oct 04 '19 15:10 0x53A

There is one pending issue with importing generics - classes and interfaces work, aliases don't.

example:

file 1

declare interface IGenericInterface<T> { value: T }
declare class GenericClass<T> { value: T }
declare type GenericAlias<T> = { value : T }
export { IGenericInterface, GenericClass, GenericAlias }

file 2:

import { IGenericInterface, GenericClass, GenericAlias } from './core/other';

will generate

type IGenericInterface<'T> = __core_other.IGenericInterface<'T>
type GenericClass<'T> = __core_other.GenericClass<'T>
type GenericAlias = __core_other.GenericAlias

when the last line should be

type GenericAlias<'T> = __core_other.GenericAlias<'T>

But I can't get them the same way, getDeclaredTypeOfSymbol returns undefined for the alias.

Would you pull this anyway? Even though it is incomplete, it's still better than before :D

0x53A avatar Oct 04 '19 15:10 0x53A

image

humhei avatar Oct 05 '19 07:10 humhei

I've merged master - I had wanted to do a few smaller PRs instead of one big one, but that kinda backfired.

Also I found another issue: default exports are not correctly exported, so it isn't 100% finished.

I'll try to complete that and add a unit test.

0x53A avatar Oct 07 '19 12:10 0x53A