microsoft / microsoft/TypeScript
Support some non-structural (nominal) type matching
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 2 j 4 h
- PR mergées (30 j)
- 132
Description
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);
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Aucun fichier, test ou point d’entrée n’est nommé. Commencez par examiner les déclarations nominales proposées ainsi que les cas d’utilisation de l’index, des callbacks et des interfaces ; le travail serait considéré comme terminé avec un design validé et le comportement de la vérification des types pour les affectations et appels invalides listés.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- Active
- Clarté
- À clarifier
- Accessibilité débutants
- 20/100