microsoft / microsoft/TypeScript

Feature: Const-literal typing for import-attribute imports

オープン
#62,919 コメント 3 件 リアクション 5 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

## 🔍 Search Terms

Keywords: Import Attributes, Const Literal Typing, Type Providers, DSL Integration, JSON Schema

Related Issues

- https://github.com/microsoft/TypeScript/issues/3136
- https://github.com/microsoft/TypeScript/issues/32063
- https://github.com/microsoft/TypeScript/issues/26552

### ✅ Viability Checklist

- [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, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

## ⭐ Suggestion

It should be possible to import a fully typed value representation via import-attributes

### Problem

When importing Json with import-attributes, TypeScript produces a non-constant data structure.

```typescript
// ----------------------------------------------------------------
// vector.json
// ----------------------------------------------------------------
{ "x": 1, "y": 2, "z": 3 }

// ----------------------------------------------------------------
// index.ts
// ----------------------------------------------------------------
import Vector from "./vector.json" with { type: "json" };

const { x, y, z } = Vector // actual = { x: number, y: number, z: number }
//
// expect = { x: 1, y: 2, z: 3 }
```

Information is lost regarding the literal values `1, 2, 3` (replaced by `number`). As information is lost on import, this makes type-mapping metadata encoded in the Json virtually impossible.

## 📃 Motivating Example

### Import Json Schema

It should be possible for libraries to infer data structures from imported schematics like Json Schema. The minimum requirement is that the imported type be a literal representation of the data.

Ref: [Inline Provided Type](https://www.typescriptlang.org/play/?target=99&module=7#code/JYWwDg9gTgLgBAbzjAnmApnAyjAhjYAYzgF84AzKCEOAclQwCMIAPWgKHYHou4A1dIRjQAzHGABnOAAUqAN2AATdIrgAVNOk4NMAoaLgBebHgKEAPEjjWbtuz2Sb+g4VDHGE7azoBcdCIwAVi60ADR2EZG2DtYsfgB2AK4gjOhQANxecFDoAI6JwDmKfgDatGzhtChhdABetAC64VHWMXAoCcmpGVlgVBiwwOgSflYt4zZttZ0paZm2cYiOGH60SbNQtKTNEw4kWdYdS750691bJKEHcNPHmqtnaRdZ+yQAfEA)

```typescript
import { type Static } from 'typebox'

// Vector3 is Provided Type

type Vector3 = Static<{ // type Vector3 = {
type: 'object', // x: number;
required: ['x', 'y', 'z'], // y: number;
properties: { // z: number;
x: { type: 'number' }, // }
y: { type: 'number' },
z: { type: 'number' }
}
}>
```

... but as import-attributes lose information for property values, the following isn't possible.

```typescript
// ----------------------------------------------------------------
// vector.json
// ----------------------------------------------------------------
{
"type": "object",
"required": ["x", "y", "z"],
"properties": {
"x": { "type": "number" }, // observed as { type: string }
"y": { "type": "number" },
"z": { "type": "number" }
}
}

// ----------------------------------------------------------------
// index.ts
// ----------------------------------------------------------------

import { type Static } from 'typebox'

import Vector3 from './vector.json' with { type: 'json' }

// Vector3 is Provided Type | Incorrect

type Vector3 = Static // type Vector3 = {
// x?: unknown;
// y?: unknown;
// z?: unknown;
// }
```

### Import TypeScript via Text

If import-attributes with `{ type: 'text' }` could also return literal string types. This would enable type safe DSL parsers to be developed for formats such as GraphQL, gRPC IDL or even TypeScript itself.

Ref: [Parse TypeScript via Constant String Literal](https://www.typescriptlang.org/play/?target=99&module=7#code/JYWwDg9gTgLgBAbzjAnmApnAKgZQMZTBgwA0yamOMAhjMHnAL5wBmUEIcA5KhgEYQAHlwBQIgPTi4AEXQtgAO2B0ICuAAVqUAM6KA5iN6YAsrQAWcALzZ8hYgB4EjMgAMRcOOkGRY5DHAA1dDwYaAAmK0R3DzhBAC44BQBXED50KGiPFATk1PToxmivH3gjQODQqABmSIRM2JyUtIyYuGzEpvzWgC9GvJamERcAPjFJcpDoGoAfCcqI6m0NdgA3YAATdHXsCm1DCjnwyKpaentTGDMAbS4gyagwrgBdYY9xsrv52vrW37--gF-cYeeIdfoAbh+gOhMN+wLafWakNhKNRcHGhQ+FSmxxodDw53MN0+U2er3RUix9xq1jqaPpgPhoNySKhDIZ8PaLPSyPZfLeUg8vTBrP5-IxQA)

```typescript
import { type TScript, type Static } from 'typebox'

// Definition Parsing
type Math = TScript<{}, `
export type Vector2 = {
x: number
y: number
}
export type Vector3 = {
x: number
y: number
z: number
}
`>

// Vector3 | Vector2 as Provided Types
type Vector2 = Static // type Vector2 = {
// x: number;
// y: number;
// }
type Vector3 = Static // type Vector3 = {
// x: number;
// y: number;
// z: number;
// }
```

## 💻 Use Cases

> What do you want to use this for?

At a high level:

- Use the TypeScript compiler to auto sync MCP protocol schematics loaded via URI (Deno). [Example](https://tsplay.dev/w6kdYN)
- Use the TypeScript compiler to parse and infer WAT/WASM interface definitions [Example](https://tsplay.dev/mbModN)
- Use the TypeScript compiler to parse foreign IDL formats like GraphQL [Reference](https://graphql.org/learn/schema/)
- Use the TypeScript compiler to derive structures from WebGL/WebGPU (WGSL) compute programs [Reference](https://www.w3.org/TR/WGSL/#intro)

---

> What workarounds are you using in the meantime?

For inference, the current workaround is to encode structures in constant string literals.

```typescript
// workable: would prefer to edit in '.graphql' and load via { type: 'text' } attribute
export const GraphQLTypes = `
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
}
`
```

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

ソースファイル、テスト、コンパイラのエントリーポイントは指定されていません。まず、既存の import-attribute の処理と、関連する型推論のテストを見つけてください。JSON およびテキストのインポートでリテラルを保持するという提案された動作を、リンクされている issue と比較し、意図された推論型を確立するテストを定義してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。