microsoft / microsoft/TypeScript

Design Meeting Notes, 2026-08-25

Open
#64,011 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Design Notes
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

# Import Attributes on Ambient Modules

https://github.com/microsoft/TypeScript/pull/63931

* ECMAScript now has stage-3 recognized `type` attributes on import statements.

```ts
// text has type `string`
import text from "./file.txt" with { "type": "text" }

// bytes has type `Uint8Array`
import bytes from "./file.whatever" with { "type": "bytes" }
```
* https://github.com/tc39/proposal-import-text
* stage 3
* https://github.com/tc39/proposal-import-bytes
* stage 2.7
* Spec explicitly will allow these, but environments are free to add their own.
* For example, browsers explicitly support `type: "css"`.
* Last discussed https://github.com/microsoft/TypeScript/issues/62615
* Big question that came up was whether we should resolve to check paths, copy as outputs.
* Leaned towards no.
* So #63931 adds support for import attributes in ambient modules.

```ts
// Could write:
declare module "*" with { "type": "text" } {
const text: string;
export default text;
}

declare module "*" with { "type": "bytes" } {
const bytes: Uint8Array;
export default bytes;
}

// For the browser:
declare module "*" with { "type": "css" } {
const css: string;
export default css;
}
```
* Idea is that these patterns are actually limited type specifications.

```ts
declare module "./file.something" with { "some-attribute": string } {
// ...
}
```
* We match specifiers against patterns and get the most specific patterns and attribute types.
* What is most-specific?
* We use a form of subtype reduction based on the type derived from the import attributes, along with longest specifier matches.
* What if they "tie"? Mutually exclusive types.
* First one in the program wins.
* Is the idea that `lib.esnext.d.ts` and `lib.dom.d.ts` will have the above import attributes?
* Yes... maybe?
* Though it's possible that now you'll accidentally end up with `lib.dom.d.ts` brought into Node.js context - pretty common unfortunately.
* True, but you need to explicitly write `type: "css"`.
* People might already have their own?
* But these would have a specific `type` pattern anyway.
* File existence?
* Something we can extend out to the future.
* File copying from inputs/outputs?
* This is what happens with JSON on certain resolution modes.
* Causes all sorts of issues (e.g. importing from `package.json`).
* Want to avoid this.
* Merging conflicting declarations?
* Maybe we can do something a little bit better on ambient module declarations.
* What about forbidding overlaps?
* Why are these types more capable just allowing unit types?
* Why allow `type: string`?
* Because you might want union types, reduce code.

```ts
declare module "*" with { "type": "md" | "markdown" } {
// ...
}
```
* Yeah, but you can just write multiple specific modules instead of using a union type. It's duplicative but it's fine.
* Also, overrides? Unions would have allowed those.

```ts
declare module "*.foo" with { "my-thing": "a" | "b" } {/*base contents*/}
declare module "*.foo" with { "my-thing": "a" } {/*overrides with more specific type for 'a'*/}

// vs.

declare module "*.foo" with { "my-thing": "a" } {/*base contents*/}
declare module "*.foo" with { "my-thing": "b" } {/*base contents*/}

// This is now a merge with the first declaration.
declare module "*.foo" with { "my-thing": "a" } {/*overrides(?) with more specific type for 'a'*/}
```
* But lots of problems that can come up with "most specific" lookup.
* Like what?
* Part of it is now like overload resolution
* Hard to diagnose which one is chosen (or _not_ chosen).
* Also, can mix poorly when types have differing IDs, working with parallel independent checkers.
* Conclusions:
* 7.1 will have unit-only types, no override behavior for `declare module`.
* This PR will not contain `lib.d.ts` updates, and they may not ship as part of 7.1.
* Future: revisit the above, plus a flag to make sure that the existence of relative file paths are actually checked when they hit a pattern.

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

Start by reading PR #63931 and the prior discussion in issue #62615 to understand the ambient-module import-attribute design. The notes conclude that 7.1 will support unit-only types without override behavior, while file-existence checks and lib.d.ts updates are future work. No specific file, test, or self-contained implementation target is identified here.

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
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.