fable-compiler / ts2fable

Parser of Typescript declaration files
http://fable.io/ts2fable/
Apache License 2.0
224 stars 34 forks source link

Unify indirect Enum-Case-Usage with all source Enum #460

Closed Booksbaum closed 1 year ago

Booksbaum commented 1 year ago

Follow up(ish) to #451

enum Kind {
    Alpha = 1,
    Beta = 2,
    Gamma = 3,
    Delta = 4,
}
interface Token<TKind extends Kind> {}

type TokenBC1 = Token<Kind.Beta | Kind.Gamma>
type TokenBC2 = Token<Kind.Beta> | Token<Kind.Gamma>

type TokenBeta = Token<Kind.Beta>
type TokenGamma = Token<Kind.Gamma>
type TokenBC3 = TokenBeta | TokenGamma

Currently:

//[...]
type TokenBC1 =
    Token<Kind>

type TokenBC2 =
    Token<Kind>

type TokenBeta =
    Token<Kind>

type TokenGamma =
    Token<Kind>

type TokenBC3 =
    U2<TokenBeta, TokenGamma>

-> Unlike TokenBC1 & 2, TokenBC3 doesn't get reduced to Token<Kind>, because it doesn't directly use Token<...>, but instead via Alias.

With this PR TokenBC3 gets reduced to Token<Kind> too:

type TokenBC3 =
    Token<Kind>




Additional: If ts2fable removes Enum-Case info (like in example above: Actual Kind Case gets reduced to Kind Type), I now put a XML comment with original TS source on that alias:

/// <remarks>
/// Original in TypeScript:  
/// <code lang="typescript">
/// Token&lt;Kind.Beta | Kind.Gamma&gt;
/// </code>
/// </remarks>
type TokenBC1 =
    Token<Kind>

/// <remarks>
/// Original in TypeScript:  
/// <code lang="typescript">
/// Token&lt;Kind.Beta&gt; | Token&lt;Kind.Gamma&gt;
/// </code>
/// </remarks>
type TokenBC2 =
    Token<Kind>

/// <remarks>
/// Original in TypeScript:  
/// <code lang="typescript">
/// Token&lt;Kind.Beta&gt;
/// </code>
/// </remarks>
type TokenBeta =
    Token<Kind>

/// <remarks>
/// Original in TypeScript:  
/// <code lang="typescript">
/// Token&lt;Kind.Gamma&gt;
/// </code>
/// </remarks>
type TokenGamma =
    Token<Kind>

/// <remarks>
/// Original in TypeScript:  
/// <code lang="typescript">
/// TokenBeta | TokenGamma
/// </code>
/// </remarks>
type TokenBC3 =
    Token<Kind>

(Unfortunately only really readable in rendered comments and not in code because of escaped < & > ... because XML :/ ...)



Note: Remark gets only added iff there was something removed:

type Simple = Token<Kind>

doesn't get a TS comment:

type Simple =
    Token<Kind>


Note: Currently only type alias gets those remarks. Interface Token<TKind> doesn't get a comment despite Kind constraint is removed:

type [<AllowNullLiteral>] Token<'TKind when 'TKind : enum<int>> =
    interface end