microsoft / microsoft/TypeScript

Feature: Const-literal typing for import-attribute imports

Aperta
#62,919 3 commenti 5 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Awaiting More Feedback Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

## 🔍 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
}
`
```

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Non sono indicati file sorgente, test o punti di ingresso del compilatore; inizia individuando la gestione esistente degli attributi di importazione e i test correlati sull’inferenza dei tipi. Confronta il comportamento proposto di mantenere i valori letterali per le importazioni JSON e di testo con le issue collegate e definisci test che stabiliscano i tipi inferiti previsti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.