microsoft / microsoft/TypeScript
Support some non-structural (nominal) type matching
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
Proposal: support non-structural typing (e.g. new user-defined base-types, or some form of basic nominal typing). This allows programmer to have more refined types supporting frequently used idioms such as:
-
Indexes that come from different tables. Because all indexes are strings (or numbers), it's easy to use the an index variable (intended for one table) with another index variable intended for a different table. Because indexes are the same type, no error is given. If we have abstract index classes this would be fixed.
-
Certain classes of functions (e.g. callbacks) can be important to be distinguished even though they have the same type. e.g. "() => void" often captures a side-effect producing function. Sometimes you want to control which ones are put into an event handler. Currently there's no way to type-check them.
-
Consider having 2 different interfaces that have different optional parameters but the same required one. In typescript you will not get a compiler error when you provide one but need the other. Sometimes this is ok, but very often this is very not ok and you would love to have a compiler error rather than be confused at run-time.
Proposal (with all type-Error-lines removed!):
// Define FooTable and FooIndex
nominal FooIndex = string; // Proposed new kind of nominal declaration.
interface FooTable {
[i: FooIndex]: { foo: number };
}
let s1: FooIndex;
let t1: FooTable;
// Define BarTable and BarIndex
nominal BarIndex = string; // Proposed new kind of nominal declaration.
interface BarTable {
[i: BarIndex]: { bar: string };
}
let s2: BarIndex;
let t2: BarTable;
// For assignment from base-types and basic structures: no type-overloading is needed.
s1 = 'foo1';
t1 = {};
t1[s1] = { foo: 1 };
s2 = 'bar1';
t2 = { 'bar1': { bar: 'barbar' }};
console.log(s2 = s1); // Proposed to be type error.
console.log(s2 == s1); // Proposed to be type error.
console.log(s2 === s1); // Proposed to be type error.
t1[s2].foo = 100; // Gives a runtime error. Proposed to be type error.
t1[s1].foo = 100;
function BadFooTest(t: FooTable) {
if (s2 in t) { // Proposed to be type error.
console.log('cool');
console.log(t[s2].foo); // Proposed to be type error.
}
}
function GoodBarTest(t: BarTable) {
if (s2 in t) {
console.log('cool');
console.log(t[s2].bar);
}
}
BadFooTest(t1); // Gives runtime error;
BadFooTest(t2); // No runtime error, Proposed to be type error.
GoodBarTest(t1); // Gives runtime error; Proposed to be type error.
GoodBarTest(t2);
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Non vengono nominati file, test o punti di ingresso. Inizia esaminando le dichiarazioni nominali proposte e i casi d’uso di index, callback e interface; per considerare il lavoro completato sarebbero necessari un design concordato e un comportamento del controllo dei tipi per le assegnazioni e le chiamate non valide elencate.
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à
- Attiva
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 20/100