microsoft / microsoft/TypeScript

Wildcard/star export from type expression

Open
#59,758 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Awaiting More Feedback Suggestion
Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔍 Search Terms
  • "export ="
  • "export type ="
  • flatten type export
  • export top-level type
  • wildcard export type
  • star export type
  • "export *"
  • "export type *"
✅ Viability Checklist
⭐ Suggestion

Introduce syntax for exporting a "spread" type:

// 1. This is based on ES export lists and spread tuple types. It would only be
//    valid for types, since modules have to be statically analyzable:
export { ...ComplexType };
export type { ...ComplexType };

// 2. Not currently valid in normal type expressions, so might be
//    unexpected, even if it mirrors valid ES syntax. However, it might be
//    something to consider allowing independently, since it's not quite the
//    same as an intersection type, and would be useful for "overwriting"
//    properties:
type Spread = { ...ComplexType };
//              ^ Member 'Complex' implicitly has an 'any' type. (7008)

// 3. These are probably too "generic" and easy to confuse with other export
//    syntax, and doesn't make the required "object" shape obvious:
export ComplexType;          // spread
export type ComplexType;     // spread
export type Other = boolean; // NOT spread

// 4. Barrel export syntax would be a bit more explicit, and mirrors their
//    respective import syntax nicely:
import type * as ComplexType from "./a.ts";
export type * from ComplexType;       // inverse of the import
export type { Foo } from ComplexType; // also potentially nice to have

// 5. An alternative based on CommonJS top-level export syntax, but probably
//    undesirable to use for ES modules:
export = { Foo: "a", Bar: 1 }; // top-level value
export type = ComplexType;     // top-level ("spread") type

I'd personally prefer (4), but if extending spreading to object types is feasible, (1) would also be a natural choice.

📃 Motivating Example

Not having "spreadable" type exports requires a lot of repetition in cases like this one, which this feature would alleviate significantly:

export type ComplexType = {
   Foo: string,
   Bar: number,
};

// A. This is how it works right now. Every type name has to be repeated three
//    times each:
export type Foo = ComplexType["Foo"];
export type Bar = ComplexType["Bar"];
export { Foo, Bar };

// B. This is what you could do instead:
export type * from ComplexType; // (4)
export type { ...ComplexType }; // (1)

// C. You could even trivially allow mapped/filtered exports
export type * from {  [K in keyof ComplexType]: K extends 'Bar' ? never : ComplexType[K]; }; // (4)
export type { [K in keyof ComplexType]: K extends 'Bar' ? never : ComplexType[K]; };         // (1)
💻 Use Cases

See Motivating Example

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No file, test, or entry point is named. Start by reviewing the proposed syntax alternatives and locating the relevant TypeScript export and type-checking paths; done would require a settled design, implementation, and regression coverage, but the issue does not choose which alternative to implement.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.