TypeScript/tests/cases/conformance/salsa/classCanExtendConstructorFunction.ts
Nathan Shively-Sanders c184184713
Add getEffectiveConstructSignatures (#27561)
* Add helpers that understand constructor functions

* getEffectiveConstructSignatures gets construct signatures from type, and
  call signatures from constructor functions if there are no construct
  signatures.
* getEffectiveConstructSignatureReturnType gets the "JS Class type" for
  constructor functions, and the return type of signatures for all other
  declarations.

This is a first step toward making constructor functions have construct
signatures instead of call signatures, which will also contribute to
fixing instantiation of generic constructor functions, which is basically
broken right now.

Note that the baselines *improve* but, because of the previously
mentioned generic problem, are still not correct. Construct signatures
for constructor functions and generic constructor functions turns out to
be an intertwined problem.

* Correct correct originalBaseType

And, for now, return anyType for generic constructor functions used as
base types. Don't give an incorrect error based on the function's return
type, which is usually void.

* Add error examples to tests

* Add construct signatures instead of getEffective* functions

* Fix typo in baseline

* Remove pesky newline

I thought I got rid of it!

* Test of constructor tag on object literal method

It doesn't work, and shouldn't in the future, because it's a runtime
error.
2018-10-15 12:47:57 -07:00

107 lines
2.3 KiB
TypeScript

// @noEmit: true
// @allowJs: true
// @checkJs: true
// @Filename: first.js
/**
* @constructor
* @param {number} numberOxen
*/
function Wagon(numberOxen) {
this.numberOxen = numberOxen
}
/** @param {Wagon[]=} wagons */
Wagon.circle = function (wagons) {
return wagons ? wagons.length : 3.14;
}
/** @param {*[]=} supplies - *[]= is my favourite type */
Wagon.prototype.load = function (supplies) {
}
/** @param {*[]=} supplies - Yep, still a great type */
Wagon.prototype.weight = supplies => supplies ? supplies.length : -1
Wagon.prototype.speed = function () {
return this.numberOxen / this.weight()
}
// ok
class Sql extends Wagon {
constructor() {
super(); // error: not enough arguments
this.foonly = 12
}
/**
* @param {Array.<string>} files
* @param {"csv" | "json" | "xmlolololol"} format
* This is not assignable, so should have a type error
*/
load(files, format) {
if (format === "xmlolololol") {
throw new Error("please do not use XML. It was a joke.");
}
else {
super.speed() // run faster
if (super.weight() < 0) {
// ????????????????????????
}
}
}
}
var db = new Sql();
db.numberOxen = db.foonly
// error, can't extend a TS constructor function
class Drakkhen extends Dragon {
}
// @Filename: second.ts
/**
* @constructor
*/
function Dragon(numberEaten: number) {
this.numberEaten = numberEaten
}
// error!
class Firedrake extends Dragon {
constructor() {
super();
}
}
// ok
class Conestoga extends Wagon {
constructor(public drunkOO: true) {
// error: wrong type
super('nope');
}
// should error since others is not optional
static circle(others: (typeof Wagon)[]) {
return others.length
}
}
var c = new Conestoga(true);
c.drunkOO
c.numberOxen
// @Filename: generic.js
/**
* @template T
* @param {T} flavour
*/
function Soup(flavour) {
this.flavour = flavour
}
/** @extends {Soup<{ claim: "ignorant" | "malicious" }>} */
class Chowder extends Soup {
log() {
return this.flavour
}
}
var soup = new Soup(1);
soup.flavour
var chowder = new Chowder({ claim: "ignorant" });
chowder.flavour.claim
var errorNoArgs = new Chowder();
var errorArgType = new Chowder(0);