microsoft / microsoft/TypeScript
Support some non-structural (nominal) type matching
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
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);
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Es werden keine Dateien, Tests oder Einstiegspunkte genannt. Beginne mit der Überprüfung der vorgeschlagenen nominalen Deklarationen sowie der Anwendungsfälle für Index, Callbacks und Interfaces; abgeschlossen wäre die Aufgabe erst mit einem abgestimmten Design und dem Verhalten der Typprüfung für die aufgeführten ungültigen Zuweisungen und Aufrufe.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Aktiv
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 20/100