microsoft / microsoft/TypeScript

A flag to make TypeScript more strict towards duck-typing classes

Offen
#42,698 15 Kommentare 25 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

Suggestion

🔍 Search Terms

JavaScript class, TypeScript interface, duck-typing, anonymous object

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

I think it might be useful if TypeScript didn't always treat classes same as interfaces. For example, I'd like to see at least a warning when assigning a compatible anonymous object to a variable of a known class type, like this (Playground link):

class C { s: string = ""; }
const o: C = { s: "123" };
console.log(o.s);
console.log(o instanceof C); // false
console.log(o.constructor.name); // Object

📃 Motivating Example

The above code compiles without any warnings, which may come as a surprise for people coming from other OOP languages, and potentially cause runtime errors.

Unlike TypeScript interfaces, classes are still "first-class citizens" in JavaScript. I believe they're are essential part of JavaScript, and their value as types should rather be elevated by TypeScript, than diminished. This might help people coming to TypeScript from other languages (like C#, Java and even JavaScript itself!) who extensively have used classes before.

In this light, the author of that code fragment probably meant to write something that looks like below (Playground link). It'd be great if TypeScript introduced a CLI option to assist with spotting cases like that.

class C { s: string = ""; }
const o: C = Object.assign(new C(), { s: "123" });
console.log(o.s);
console.log(o instanceof C); // true
console.log(o.constructor.name); // C

On a side note, if I do this (Playground link):

class C { s: string = ""; }
const o: C = new C();
const o2: C = new o.constructor();
console.log(o2.constructor.name);

I don't understand the warning "This expression is not constructable. Type 'Function' has no construct signatures.(2351)" for the const o2: C = new o.constructor() line. It looks perfectly valid to me, the class type should be deductible in the above code fragment.

I can think of const o2: C = new (o.constructor as {new(): C})() as a workaround, or const o2: C = new (o.constructor as any)() as C. I don't like either, because at least the base class type for o is already known in this lexical scope, it's C.

💻 Use Cases

I hope I've covered that with the second code fragment, but also please see @Barbiero's comment below. Thanks for considering this idea.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Das Issue nennt keine Repository-Dateien oder Tests; beginne mit den beiden TypeScript Playground-Beispielen und vergleiche deren aktuelle Diagnosen und Laufzeitkommentare. Lege das beabsichtigte Opt-in-Verhalten für die Zuweisung anonymer Objekte an Klassentypen und für o.constructor fest, wobei der Abschluss durch Tests gekennzeichnet wird, die die angeforderten Diagnosen und das unveränderte bestehende Verhalten abdecken.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript, typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.