Compare commits
9 commits
main
...
contextual
Author | SHA1 | Date | |
---|---|---|---|
270843ffce | |||
5872fdbf25 | |||
02e5a31b40 | |||
958c6afa00 | |||
3747e2969f | |||
fd8819a333 | |||
d9392e9443 | |||
0181886d10 | |||
ea43f4626b |
|
@ -3051,6 +3051,14 @@ namespace ts {
|
|||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
// use type from base class' property if present
|
||||
if (declaration.kind === SyntaxKind.PropertyDeclaration) {
|
||||
const type = getTypeOfBasePropertyDeclaration(<PropertyDeclaration>declaration);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.kind === SyntaxKind.Parameter) {
|
||||
const func = <FunctionLikeDeclaration>declaration.parent;
|
||||
// For a parameter of a set accessor, use the type of the get accessor if one is present
|
||||
|
@ -3434,6 +3442,20 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
|
||||
function getTypeOfBasePropertyDeclaration(declaration: PropertyDeclaration) {
|
||||
if (declaration.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
const parent = <ClassLikeDeclaration>declaration.parent;
|
||||
const baseClasses = getBaseTypes(<InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(parent)));
|
||||
const implementsNode = getClassImplementsHeritageClauseElements(parent) || ([] as NodeArray<ExpressionWithTypeArguments>);
|
||||
const allBases = getIntersectionType(baseClasses.concat(map(implementsNode, getTypeFromTypeReference)));
|
||||
const baseProperty = getPropertyOfType(allBases, declaration.symbol.name);
|
||||
if (baseProperty) {
|
||||
return getTypeOfSymbol(baseProperty);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTargetType(type: ObjectType): Type {
|
||||
return type.flags & TypeFlags.Reference ? (<TypeReference>type).target : type;
|
||||
}
|
||||
|
@ -5900,7 +5922,7 @@ namespace ts {
|
|||
// Returns true if the given expression contains (at any level of nesting) a function or arrow expression
|
||||
// that is subject to contextual typing.
|
||||
function isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElement): boolean {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isMethod(node));
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
|
@ -5933,8 +5955,8 @@ namespace ts {
|
|||
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration {
|
||||
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
|
||||
function isContextSensitiveFunctionOrMethod(func: Node): func is FunctionExpression | MethodDeclaration {
|
||||
return (isFunctionExpressionOrArrowFunction(func) || isMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
|
||||
}
|
||||
|
||||
function getTypeWithoutSignatures(type: Type): Type {
|
||||
|
@ -9376,7 +9398,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
if (isContextSensitiveFunctionOrMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
return contextualSignature.thisParameter;
|
||||
|
@ -9389,7 +9411,7 @@ namespace ts {
|
|||
// Return contextual type of parameter or undefined if no contextual type is available
|
||||
function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type {
|
||||
const func = parameter.parent;
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
if (isContextSensitiveFunctionOrMethod(func)) {
|
||||
const iife = getImmediatelyInvokedFunctionExpression(func);
|
||||
if (iife) {
|
||||
const indexOfParameter = indexOf(func.parameters, parameter);
|
||||
|
@ -9443,6 +9465,12 @@ namespace ts {
|
|||
if (declaration.type) {
|
||||
return getTypeFromTypeNode(declaration.type);
|
||||
}
|
||||
if (declaration.kind === SyntaxKind.PropertyDeclaration) {
|
||||
const type = getTypeOfBasePropertyDeclaration(<PropertyDeclaration>declaration);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
if (declaration.kind === SyntaxKind.Parameter) {
|
||||
const type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
if (type) {
|
||||
|
@ -9816,16 +9844,22 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature {
|
||||
// Only function expressions, arrow functions, and object literal methods are contextually typed.
|
||||
return isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)
|
||||
// Only function expressions, arrow functions, and methods are contextually typed.
|
||||
return isFunctionExpressionOrArrowFunction(node) || isMethod(node)
|
||||
? getContextualSignature(<FunctionExpression>node)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) {
|
||||
return isObjectLiteralMethod(node) ?
|
||||
getContextualTypeForObjectLiteralMethod(node) :
|
||||
getApparentTypeOfContextualType(node);
|
||||
if (isFunctionExpressionOrArrowFunction(node)) {
|
||||
return getApparentTypeOfContextualType(node);
|
||||
}
|
||||
else if (isObjectLiteralMethod(node)) {
|
||||
return getContextualTypeForObjectLiteralMethod(node);
|
||||
}
|
||||
else if (isMethod(node)) {
|
||||
return getTypeOfBasePropertyDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the contextual signature for a given expression node. A contextual type provides a
|
||||
|
@ -9834,7 +9868,7 @@ namespace ts {
|
|||
// all identical ignoring their return type, the result is same signature but with return type as
|
||||
// union type of return types from these signatures
|
||||
function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isMethod(node));
|
||||
const type = getContextualTypeForFunctionLikeDeclaration(node);
|
||||
if (!type) {
|
||||
return undefined;
|
||||
|
|
|
@ -864,6 +864,10 @@ namespace ts {
|
|||
return predicate && predicate.kind === TypePredicateKind.Identifier;
|
||||
}
|
||||
|
||||
export function isMethod(node: Node): node is MethodDeclaration {
|
||||
return node && node.kind === SyntaxKind.MethodDeclaration;
|
||||
}
|
||||
|
||||
export function isThisTypePredicate(predicate: TypePredicate): predicate is ThisTypePredicate {
|
||||
return predicate && predicate.kind === TypePredicateKind.This;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,11 @@ tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstra
|
|||
tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(19,1): error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(24,7): error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'.
|
||||
Types of property 'num' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(30,7): error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'.
|
||||
Types of property 'num' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(33,7): error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'.
|
||||
Types of property 'num' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or non-abstract.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or non-abstract.
|
||||
tests/cases/compiler/abstractPropertyNegative.ts(40,9): error TS2676: Accessors must both be abstract or non-abstract.
|
||||
|
@ -65,11 +61,9 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors
|
|||
abstract num: number;
|
||||
}
|
||||
class WrongTypePropertyImpl extends WrongTypeProperty {
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'.
|
||||
!!! error TS2415: Types of property 'num' are incompatible.
|
||||
!!! error TS2415: Type 'string' is not assignable to type 'number'.
|
||||
num = "nope, wrong";
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
}
|
||||
abstract class WrongTypeAccessor {
|
||||
abstract get num(): number;
|
||||
|
@ -82,11 +76,9 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors
|
|||
get num() { return "nope, wrong"; }
|
||||
}
|
||||
class WrongTypeAccessorImpl2 extends WrongTypeAccessor {
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'.
|
||||
!!! error TS2415: Types of property 'num' are incompatible.
|
||||
!!! error TS2415: Type 'string' is not assignable to type 'number'.
|
||||
num = "nope, wrong";
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
}
|
||||
|
||||
abstract class AbstractAccessorMismatch {
|
||||
|
|
|
@ -29,7 +29,7 @@ class D extends C<IHasVisualizationModel> {
|
|||
>IHasVisualizationModel : IHasVisualizationModel
|
||||
|
||||
x = moduleA;
|
||||
>x : typeof moduleA
|
||||
>x : IHasVisualizationModel
|
||||
>moduleA : typeof moduleA
|
||||
}
|
||||
=== tests/cases/compiler/aliasUsageInTypeArgumentOfExtendsClause_backbone.ts ===
|
||||
|
|
|
@ -29,14 +29,14 @@ class F extends C { f }
|
|||
class C1 implements base1 { i = "foo"; c }
|
||||
>C1 : C1
|
||||
>base1 : base1
|
||||
>i : string
|
||||
>i : any
|
||||
>"foo" : string
|
||||
>c : any
|
||||
|
||||
class D1 extends C1 { i = "bar"; d }
|
||||
>D1 : D1
|
||||
>C1 : C1
|
||||
>i : string
|
||||
>i : any
|
||||
>"bar" : string
|
||||
>d : any
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
tests/cases/compiler/convertKeywordsYes.ts(175,5): error TS2322: Type 'number' is not assignable to type 'Function'.
|
||||
tests/cases/compiler/convertKeywordsYes.ts(292,11): error TS1213: Identifier expected. 'implements' is a reserved word in strict mode. Class definitions are automatically in strict mode.
|
||||
tests/cases/compiler/convertKeywordsYes.ts(293,11): error TS1213: Identifier expected. 'interface' is a reserved word in strict mode. Class definitions are automatically in strict mode.
|
||||
tests/cases/compiler/convertKeywordsYes.ts(294,11): error TS1213: Identifier expected. 'let' is a reserved word in strict mode. Class definitions are automatically in strict mode.
|
||||
|
@ -9,7 +10,7 @@ tests/cases/compiler/convertKeywordsYes.ts(301,11): error TS1213: Identifier exp
|
|||
tests/cases/compiler/convertKeywordsYes.ts(303,11): error TS1213: Identifier expected. 'yield' is a reserved word in strict mode. Class definitions are automatically in strict mode.
|
||||
|
||||
|
||||
==== tests/cases/compiler/convertKeywordsYes.ts (9 errors) ====
|
||||
==== tests/cases/compiler/convertKeywordsYes.ts (10 errors) ====
|
||||
// reserved ES5 future in strict mode
|
||||
|
||||
var constructor = 0;
|
||||
|
@ -185,6 +186,8 @@ tests/cases/compiler/convertKeywordsYes.ts(303,11): error TS1213: Identifier exp
|
|||
|
||||
class bigClass {
|
||||
public "constructor" = 0;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'Function'.
|
||||
public any = 0;
|
||||
public boolean = 0;
|
||||
public implements = 0;
|
||||
|
|
|
@ -36,13 +36,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
|
|||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(55,7): error TS2420: Class 'C4' incorrectly implements interface 'F2'.
|
||||
Types of property 'd4' are incompatible.
|
||||
Type '({x, y, c}: { x: any; y: any; c: any; }) => void' is not assignable to type '({x, y, z}?: { x: any; y: any; z: any; }) => any'.
|
||||
Types of parameters '__0' and '__0' are incompatible.
|
||||
Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'.
|
||||
Property 'c' is missing in type '{ x: any; y: any; z: any; }'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,15): error TS2459: Type '{ x: any; y: any; z: any; }' has no property 'c' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,18): error TS2300: Duplicate identifier 'number'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,26): error TS2300: Duplicate identifier 'number'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,34): error TS2300: Duplicate identifier 'number'.
|
||||
|
@ -159,17 +154,12 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
|
|||
}
|
||||
|
||||
class C4 implements F2 {
|
||||
~~
|
||||
!!! error TS2420: Class 'C4' incorrectly implements interface 'F2'.
|
||||
!!! error TS2420: Types of property 'd4' are incompatible.
|
||||
!!! error TS2420: Type '({x, y, c}: { x: any; y: any; c: any; }) => void' is not assignable to type '({x, y, z}?: { x: any; y: any; z: any; }) => any'.
|
||||
!!! error TS2420: Types of parameters '__0' and '__0' are incompatible.
|
||||
!!! error TS2420: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'.
|
||||
!!! error TS2420: Property 'c' is missing in type '{ x: any; y: any; z: any; }'.
|
||||
d3([a, b, c]?) { } // Error, binding pattern can't be optional in implementation signature
|
||||
~~~~~~~~~~
|
||||
!!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
|
||||
d4({x, y, c}) { }
|
||||
~
|
||||
!!! error TS2459: Type '{ x: any; y: any; z: any; }' has no property 'c' and no string index signature.
|
||||
e0([a, b, q]) { }
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts(25,9): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts(28,9): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts(32,9): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts(35,9): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts(54,7): error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping1.ts (5 errors) ====
|
||||
interface Event {
|
||||
time: number;
|
||||
}
|
||||
interface Base {
|
||||
superHandle: (e: Event) => number;
|
||||
}
|
||||
interface Listener extends Base {
|
||||
handle: (e: Event) => void;
|
||||
}
|
||||
interface Ringer {
|
||||
ring: (times: number) => void;
|
||||
}
|
||||
interface StringLiteral {
|
||||
literal(): "A";
|
||||
literals: "A" | "B";
|
||||
}
|
||||
|
||||
abstract class Watcher {
|
||||
abstract watch(e: Event): number;
|
||||
}
|
||||
|
||||
class Alarm extends Watcher implements Listener, Ringer, StringLiteral {
|
||||
str: string;
|
||||
handle = e => {
|
||||
this.str = e.time; // error
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
superHandle = e => {
|
||||
this.str = e.time; // error
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
return e.time;
|
||||
}
|
||||
ring(times) {
|
||||
this.str = times; // error
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
watch(e) {
|
||||
this.str = e.time; // error
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
return e.time;
|
||||
}
|
||||
literal() {
|
||||
return "A"; // ok: "A" is assignable to "A"
|
||||
}
|
||||
literals = "A"; // ok: "A" is assignable to "A" | "B"
|
||||
}
|
||||
|
||||
interface A {
|
||||
q(n: string): void;
|
||||
}
|
||||
interface B {
|
||||
q(n: number): void;
|
||||
}
|
||||
class C {
|
||||
r: number;
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
q(n) { // error, n is implicitly any because A.q and B.q exist
|
||||
~
|
||||
!!! error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
n.length; // and the unioned type has no signature
|
||||
n.toFixed; // (even though the constituent types each do)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//// [implementedPropertyContextualTyping1.ts]
|
||||
interface Event {
|
||||
time: number;
|
||||
}
|
||||
interface Base {
|
||||
superHandle: (e: Event) => number;
|
||||
}
|
||||
interface Listener extends Base {
|
||||
handle: (e: Event) => void;
|
||||
}
|
||||
interface Ringer {
|
||||
ring: (times: number) => void;
|
||||
}
|
||||
interface StringLiteral {
|
||||
literal(): "A";
|
||||
literals: "A" | "B";
|
||||
}
|
||||
|
||||
abstract class Watcher {
|
||||
abstract watch(e: Event): number;
|
||||
}
|
||||
|
||||
class Alarm extends Watcher implements Listener, Ringer, StringLiteral {
|
||||
str: string;
|
||||
handle = e => {
|
||||
this.str = e.time; // error
|
||||
}
|
||||
superHandle = e => {
|
||||
this.str = e.time; // error
|
||||
return e.time;
|
||||
}
|
||||
ring(times) {
|
||||
this.str = times; // error
|
||||
}
|
||||
watch(e) {
|
||||
this.str = e.time; // error
|
||||
return e.time;
|
||||
}
|
||||
literal() {
|
||||
return "A"; // ok: "A" is assignable to "A"
|
||||
}
|
||||
literals = "A"; // ok: "A" is assignable to "A" | "B"
|
||||
}
|
||||
|
||||
interface A {
|
||||
q(n: string): void;
|
||||
}
|
||||
interface B {
|
||||
q(n: number): void;
|
||||
}
|
||||
class C {
|
||||
r: number;
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
q(n) { // error, n is implicitly any because A.q and B.q exist
|
||||
n.length; // and the unioned type has no signature
|
||||
n.toFixed; // (even though the constituent types each do)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [implementedPropertyContextualTyping1.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Watcher = (function () {
|
||||
function Watcher() {
|
||||
}
|
||||
return Watcher;
|
||||
}());
|
||||
var Alarm = (function (_super) {
|
||||
__extends(Alarm, _super);
|
||||
function Alarm() {
|
||||
var _this = this;
|
||||
_super.apply(this, arguments);
|
||||
this.handle = function (e) {
|
||||
_this.str = e.time; // error
|
||||
};
|
||||
this.superHandle = function (e) {
|
||||
_this.str = e.time; // error
|
||||
return e.time;
|
||||
};
|
||||
this.literals = "A"; // ok: "A" is assignable to "A" | "B"
|
||||
}
|
||||
Alarm.prototype.ring = function (times) {
|
||||
this.str = times; // error
|
||||
};
|
||||
Alarm.prototype.watch = function (e) {
|
||||
this.str = e.time; // error
|
||||
return e.time;
|
||||
};
|
||||
Alarm.prototype.literal = function () {
|
||||
return "A"; // ok: "A" is assignable to "A"
|
||||
};
|
||||
return Alarm;
|
||||
}(Watcher));
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var Multiple = (function (_super) {
|
||||
__extends(Multiple, _super);
|
||||
function Multiple() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
Multiple.prototype.q = function (n) {
|
||||
n.length; // and the unioned type has no signature
|
||||
n.toFixed; // (even though the constituent types each do)
|
||||
};
|
||||
return Multiple;
|
||||
}(C));
|
|
@ -0,0 +1,39 @@
|
|||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping2.ts(20,1): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping2.ts(21,1): error TS2322: Type 'boolean' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping2.ts(22,1): error TS2322: Type 'number' is not assignable to type '[number, number]'.
|
||||
tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping2.ts(23,24): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping2.ts (4 errors) ====
|
||||
interface Long {
|
||||
length: number;
|
||||
}
|
||||
interface Lol {
|
||||
canhaz: string;
|
||||
}
|
||||
interface Ceiling {
|
||||
location: { [coordinates: string]: [number, number] };
|
||||
}
|
||||
interface Invisible {
|
||||
invisibles: string[];
|
||||
}
|
||||
class Cat implements Long, Lol, Ceiling, Invisible {
|
||||
length = undefined;
|
||||
canhaz = null;
|
||||
location = {};
|
||||
invisibles = [];
|
||||
}
|
||||
const lolCat = new Cat();
|
||||
lolCat.length = "wat";
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
lolCat.canhaz = false;
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'boolean' is not assignable to type 'string'.
|
||||
lolCat.location['ceiling'] = -1;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type '[number, number]'.
|
||||
lolCat.invisibles.push(0);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//// [implementedPropertyContextualTyping2.ts]
|
||||
interface Long {
|
||||
length: number;
|
||||
}
|
||||
interface Lol {
|
||||
canhaz: string;
|
||||
}
|
||||
interface Ceiling {
|
||||
location: { [coordinates: string]: [number, number] };
|
||||
}
|
||||
interface Invisible {
|
||||
invisibles: string[];
|
||||
}
|
||||
class Cat implements Long, Lol, Ceiling, Invisible {
|
||||
length = undefined;
|
||||
canhaz = null;
|
||||
location = {};
|
||||
invisibles = [];
|
||||
}
|
||||
const lolCat = new Cat();
|
||||
lolCat.length = "wat";
|
||||
lolCat.canhaz = false;
|
||||
lolCat.location['ceiling'] = -1;
|
||||
lolCat.invisibles.push(0);
|
||||
|
||||
|
||||
//// [implementedPropertyContextualTyping2.js]
|
||||
var Cat = (function () {
|
||||
function Cat() {
|
||||
this.length = undefined;
|
||||
this.canhaz = null;
|
||||
this.location = {};
|
||||
this.invisibles = [];
|
||||
}
|
||||
return Cat;
|
||||
}());
|
||||
var lolCat = new Cat();
|
||||
lolCat.length = "wat";
|
||||
lolCat.canhaz = false;
|
||||
lolCat.location['ceiling'] = -1;
|
||||
lolCat.invisibles.push(0);
|
|
@ -0,0 +1,42 @@
|
|||
//// [implementedPropertyContextualTyping3.ts]
|
||||
interface A {
|
||||
p: string;
|
||||
r: string;
|
||||
s: string;
|
||||
}
|
||||
interface B {
|
||||
p: number;
|
||||
r: boolean;
|
||||
s: string;
|
||||
}
|
||||
class C {
|
||||
r: number;
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
p = undefined; // ok, Multiple.p: string & number
|
||||
r = null; // OK, r: string & boolean & number
|
||||
s = null; // OK, s: string
|
||||
}
|
||||
|
||||
|
||||
//// [implementedPropertyContextualTyping3.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var Multiple = (function (_super) {
|
||||
__extends(Multiple, _super);
|
||||
function Multiple() {
|
||||
_super.apply(this, arguments);
|
||||
this.p = undefined; // ok, Multiple.p: string & number
|
||||
this.r = null; // OK, r: string & boolean & number
|
||||
this.s = null; // OK, s: string
|
||||
}
|
||||
return Multiple;
|
||||
}(C));
|
|
@ -0,0 +1,48 @@
|
|||
=== tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping3.ts ===
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(implementedPropertyContextualTyping3.ts, 0, 0))
|
||||
|
||||
p: string;
|
||||
>p : Symbol(A.p, Decl(implementedPropertyContextualTyping3.ts, 0, 13))
|
||||
|
||||
r: string;
|
||||
>r : Symbol(A.r, Decl(implementedPropertyContextualTyping3.ts, 1, 14))
|
||||
|
||||
s: string;
|
||||
>s : Symbol(A.s, Decl(implementedPropertyContextualTyping3.ts, 2, 14))
|
||||
}
|
||||
interface B {
|
||||
>B : Symbol(B, Decl(implementedPropertyContextualTyping3.ts, 4, 1))
|
||||
|
||||
p: number;
|
||||
>p : Symbol(B.p, Decl(implementedPropertyContextualTyping3.ts, 5, 13))
|
||||
|
||||
r: boolean;
|
||||
>r : Symbol(B.r, Decl(implementedPropertyContextualTyping3.ts, 6, 14))
|
||||
|
||||
s: string;
|
||||
>s : Symbol(B.s, Decl(implementedPropertyContextualTyping3.ts, 7, 15))
|
||||
}
|
||||
class C {
|
||||
>C : Symbol(C, Decl(implementedPropertyContextualTyping3.ts, 9, 1))
|
||||
|
||||
r: number;
|
||||
>r : Symbol(C.r, Decl(implementedPropertyContextualTyping3.ts, 10, 9))
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
>Multiple : Symbol(Multiple, Decl(implementedPropertyContextualTyping3.ts, 12, 1))
|
||||
>C : Symbol(C, Decl(implementedPropertyContextualTyping3.ts, 9, 1))
|
||||
>A : Symbol(A, Decl(implementedPropertyContextualTyping3.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(implementedPropertyContextualTyping3.ts, 4, 1))
|
||||
|
||||
p = undefined; // ok, Multiple.p: string & number
|
||||
>p : Symbol(Multiple.p, Decl(implementedPropertyContextualTyping3.ts, 13, 42))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
r = null; // OK, r: string & boolean & number
|
||||
>r : Symbol(Multiple.r, Decl(implementedPropertyContextualTyping3.ts, 14, 18))
|
||||
|
||||
s = null; // OK, s: string
|
||||
>s : Symbol(Multiple.s, Decl(implementedPropertyContextualTyping3.ts, 15, 13))
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
=== tests/cases/conformance/expressions/contextualTyping/implementedPropertyContextualTyping3.ts ===
|
||||
interface A {
|
||||
>A : A
|
||||
|
||||
p: string;
|
||||
>p : string
|
||||
|
||||
r: string;
|
||||
>r : string
|
||||
|
||||
s: string;
|
||||
>s : string
|
||||
}
|
||||
interface B {
|
||||
>B : B
|
||||
|
||||
p: number;
|
||||
>p : number
|
||||
|
||||
r: boolean;
|
||||
>r : boolean
|
||||
|
||||
s: string;
|
||||
>s : string
|
||||
}
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
r: number;
|
||||
>r : number
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
>Multiple : Multiple
|
||||
>C : C
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
p = undefined; // ok, Multiple.p: string & number
|
||||
>p : string & number
|
||||
>undefined : undefined
|
||||
|
||||
r = null; // OK, r: string & boolean & number
|
||||
>r : number & string & boolean
|
||||
>null : null
|
||||
|
||||
s = null; // OK, s: string
|
||||
>s : string
|
||||
>null : null
|
||||
}
|
||||
|
|
@ -142,6 +142,6 @@ declare class Base {
|
|||
f?(): number;
|
||||
}
|
||||
declare class Derived extends Base {
|
||||
a: number;
|
||||
a: number | undefined;
|
||||
f(): number;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ class Derived extends Base {
|
|||
>Base : Base
|
||||
|
||||
a = 1;
|
||||
>a : number
|
||||
>a : number | undefined
|
||||
>1 : number
|
||||
|
||||
f(): number { return 1; }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class 'C1' incorrectly implements interface 'I1'.
|
||||
Types of property 'method' are incompatible.
|
||||
Type '(a: number, b: any) => void' is not assignable to type '() => any'.
|
||||
Type '(a: any, b: any) => void' is not assignable to type '() => any'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/requiredInitializedParameter2.ts (1 errors) ====
|
||||
|
@ -12,6 +12,6 @@ tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class
|
|||
~~
|
||||
!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'.
|
||||
!!! error TS2420: Types of property 'method' are incompatible.
|
||||
!!! error TS2420: Type '(a: number, b: any) => void' is not assignable to type '() => any'.
|
||||
!!! error TS2420: Type '(a: any, b: any) => void' is not assignable to type '() => any'.
|
||||
method(a = 0, b) { }
|
||||
}
|
|
@ -23,5 +23,5 @@ interface I1 {
|
|||
method(): any;
|
||||
}
|
||||
declare class C1 implements I1 {
|
||||
method(a?: number, b?: any): void;
|
||||
method(a?: any, b?: any): void;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ class C1 implements I1 {
|
|||
>I1 : I1
|
||||
|
||||
method(a = 0, b?) { }
|
||||
>method : (a?: number, b?: any) => void
|
||||
>a : number
|
||||
>method : (a?: any, b?: any) => void
|
||||
>a : any
|
||||
>0 : number
|
||||
>b : any
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// @noImplicitAny: true
|
||||
interface Event {
|
||||
time: number;
|
||||
}
|
||||
interface Base {
|
||||
superHandle: (e: Event) => number;
|
||||
}
|
||||
interface Listener extends Base {
|
||||
handle: (e: Event) => void;
|
||||
}
|
||||
interface Ringer {
|
||||
ring: (times: number) => void;
|
||||
}
|
||||
interface StringLiteral {
|
||||
literal(): "A";
|
||||
literals: "A" | "B";
|
||||
}
|
||||
|
||||
abstract class Watcher {
|
||||
abstract watch(e: Event): number;
|
||||
}
|
||||
|
||||
class Alarm extends Watcher implements Listener, Ringer, StringLiteral {
|
||||
str: string;
|
||||
handle = e => {
|
||||
this.str = e.time; // error
|
||||
}
|
||||
superHandle = e => {
|
||||
this.str = e.time; // error
|
||||
return e.time;
|
||||
}
|
||||
ring(times) {
|
||||
this.str = times; // error
|
||||
}
|
||||
watch(e) {
|
||||
this.str = e.time; // error
|
||||
return e.time;
|
||||
}
|
||||
literal() {
|
||||
return "A"; // ok: "A" is assignable to "A"
|
||||
}
|
||||
literals = "A"; // ok: "A" is assignable to "A" | "B"
|
||||
}
|
||||
|
||||
interface A {
|
||||
q(n: string): void;
|
||||
}
|
||||
interface B {
|
||||
q(n: number): void;
|
||||
}
|
||||
class C {
|
||||
r: number;
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
q(n) { // error, n is implicitly any because A.q and B.q exist
|
||||
n.length; // and the unioned type has no signature
|
||||
n.toFixed; // (even though the constituent types each do)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
interface Long {
|
||||
length: number;
|
||||
}
|
||||
interface Lol {
|
||||
canhaz: string;
|
||||
}
|
||||
interface Ceiling {
|
||||
location: { [coordinates: string]: [number, number] };
|
||||
}
|
||||
interface Invisible {
|
||||
invisibles: string[];
|
||||
}
|
||||
class Cat implements Long, Lol, Ceiling, Invisible {
|
||||
length = undefined;
|
||||
canhaz = null;
|
||||
location = {};
|
||||
invisibles = [];
|
||||
}
|
||||
const lolCat = new Cat();
|
||||
lolCat.length = "wat";
|
||||
lolCat.canhaz = false;
|
||||
lolCat.location['ceiling'] = -1;
|
||||
lolCat.invisibles.push(0);
|
|
@ -0,0 +1,19 @@
|
|||
// @noImplicitAny: true
|
||||
interface A {
|
||||
p: string;
|
||||
r: string;
|
||||
s: string;
|
||||
}
|
||||
interface B {
|
||||
p: number;
|
||||
r: boolean;
|
||||
s: string;
|
||||
}
|
||||
class C {
|
||||
r: number;
|
||||
}
|
||||
class Multiple extends C implements A, B {
|
||||
p = undefined; // ok, Multiple.p: string & number
|
||||
r = null; // OK, r: string & boolean & number
|
||||
s = null; // OK, s: string
|
||||
}
|
Loading…
Reference in a new issue