Typescript: [feature request] destructured type assignment

Created on 10 May 2019  路  4Comments  路  Source: microsoft/TypeScript

Search Terms

typescript destructuring types

Suggestion

We can currently do:

type Lane = import('../Lane').Lane

But it would be nifty to be able to do:

type {Lane} = import('../Lane')

And taking it further, grab more things at once:

type {Lane, LaneColor, LaneSize} = import('../Lane')

instead of having to write

type Lane = import('../Lane').Lane
type LaneColor = import('../Lane').LaneColor
type LaneSize = import('../Lane').LaneSize

Use Cases

convenience

Examples

see above

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.
Awaiting More Feedback Suggestion

Most helpful comment

@AlCalzone it doesn't interact well with the rest of the type system. For example you cannot use mapped types to express the type of a function that modifies a module's entire API.

All 4 comments

Whats the problem with just doing this?

import {Lane, LaneColor, LaneSize} from './Lane';

@AlCalzone it doesn't interact well with the rest of the type system. For example you cannot use mapped types to express the type of a function that modifies a module's entire API.

@AlCalzone @ilogico @XGHeaven

If TypeScript is adhering to ES module specification, then import {Lane, LaneColor, LaneSize} from './Lane'; will create a runtime import, meaning that the './Lane' module will be evaluated, and anything in the top level of the module will be executed.

In other words, I would expect that if I write

import './Lane';

that the ./Lane module will be evaluated, just the same as if I write

import {Lane, LaneColor, LaneSize} from './Lane';

So, to specifically create a compile-time-only import, used only by the type system (assuming TypeScript follows ES module specifications), then I can currently write

type Lane = import('../Lane').Lane
type LaneColor = import('../Lane').LaneColor
type LaneSize = import('../Lane').LaneSize

It is important the ES modules in TypeScript behave the same as spec'd in JavaScript, and thus a type import is a nice way to avoid side-effects from runtime imports.

It is important the ES modules in TypeScript behave the same as spec'd in JavaScript, and thus a type import is a nice way to avoid side-effects from runtime imports.

In practice, I believe TS doesn't emit an import statement when it seems like the import is only being used to grab a type declaration. That said, there are other use cases for what you're describing, e.g., when the types are nested:

import { NodeTypes } from "mypckg";

type X = NodeTypes.X;
type Y = NodeTypes.Y;

// Nicer
type { X, Y } = NodeTypes;
Was this page helpful?
0 / 5 - 0 ratings

Related issues

DanielRosenwasser picture DanielRosenwasser  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

siddjain picture siddjain  路  3Comments

manekinekko picture manekinekko  路  3Comments

uber5001 picture uber5001  路  3Comments