microsoft / microsoft/TypeScript

Represent the types of function parameters that mutate inside the function.

Aperta
#22,865 9 commenti 19 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
1g 19h
PR unite (30g)
117

Descrizione

In JavaScript is possible to mutate objects inside functions. Right now, the following code in JavaScript:

function merge(x,y) {
  Object.assign(x,y);
} 

let x = {a: 1};   
merge(x, {b: 2});
console.log(x.b);

Can't be written in TypeScript without casting the type. There are a few options whose type definition is wrong in all scenarios I can think of (maybe I'm missing a better option):

Option 1

let x: {a: number, b: number} = {a: 1}; // Error, missing b
merge(x, {b: 2});

Option 2

let x: {a: number, b: number} = {a: 1, b: 2};
merge(x, {b: null});
// From here, x.b is not a number anymore, but you could do
let y: number= x.b;

Suggestion

There could be an extension to function parameter definition like the following:

// then keyword indicates that before it can be type A, and after it will be of type A&B.
function merge<A,B>(x: A then x2: A&B, y: B) {
  Object.assign(x2,y);
}

let x: {a: number, b: number} = {a: 1, b: 2};
merge(x, {b: null});
// Here, type of x is {a: number, b: number} & {b: null}
x.b; // Type null

There, we indicate that whatever type was x before, now it is something different. The code above could be written in TypeScript as follows:

// then keyword indicates that before it can be type A, and after it will be of type A&B.
function merge<A,B>(x: A, y: B) {
  Object.assign(x,y);
}

let x: {a: number, b: number} = {a: 1, b: 2};
merge(x, {b: null});
// Here, type of x is {a: number, b: number} & {b: null}
let xAfterMerge = x as {a: number, b: number} & {b: null};
// Since this line, x should not be used but xAfterMerge
xAfterMerge.b; // Type null
Another example
interface Before {
  address: string;
}

interface After {
  addr: string;
}

function map(userb: Before then usera: After) {
   usera.addr = userb.address;
   delete userb.address;
}

let u = {adress: "my street"};
map(u);
console.log(u.addr);

That could be syntax sugar for this:

interface Before {
  address: string;
}

interface After {
  addr: string;
}

function map(userb: any) {
   userb.addr = userb.address;
   delete userb.address;
}

let u = {adress: "my street"};
map(u); 
console.log((u as After).addr);

Syntax

It could be something like:

identifier: type *then* identifier: type  

With the identifiers being different, and with the types being mandatory an extension of Object.

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

Inizia esaminando gli esempi proposti di merge e map, inclusa la sintassi suggerita del parametro then e il comportamento dei tipi prima e dopo. Determina se la proposta ha una semantica definita per la mutazione, gli alias, l’eliminazione delle proprietà e la nullabilità; il lavoro sarebbe considerato concluso quando esistesse un design concordato abbastanza preciso da guidare l’implementazione e i test.

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

Valutazione

Stack tecnologico
javascript, 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.