Merge pull request #8463 from Microsoft/this-types-for-accessors
This types for accessors
This commit is contained in:
commit
a715c45f25
|
@ -2924,7 +2924,12 @@ namespace ts {
|
||||||
if (func.kind === SyntaxKind.SetAccessor && !hasDynamicName(func)) {
|
if (func.kind === SyntaxKind.SetAccessor && !hasDynamicName(func)) {
|
||||||
const getter = <AccessorDeclaration>getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor);
|
const getter = <AccessorDeclaration>getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor);
|
||||||
if (getter) {
|
if (getter) {
|
||||||
return getReturnTypeOfSignature(getSignatureFromDeclaration(getter));
|
const signature = getSignatureFromDeclaration(getter);
|
||||||
|
const thisParameter = getAccessorThisParameter(func as AccessorDeclaration);
|
||||||
|
if (thisParameter && declaration === thisParameter) {
|
||||||
|
return signature.thisType;
|
||||||
|
}
|
||||||
|
return getReturnTypeOfSignature(signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use contextual parameter type if one is available
|
// Use contextual parameter type if one is available
|
||||||
|
@ -3140,6 +3145,16 @@ namespace ts {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAnnotatedAccessorThisType(accessor: AccessorDeclaration): Type {
|
||||||
|
if (accessor) {
|
||||||
|
const parameter = getAccessorThisParameter(accessor);
|
||||||
|
if (parameter && parameter.type) {
|
||||||
|
return getTypeFromTypeNode(accessor.parameters[0].type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function getTypeOfAccessors(symbol: Symbol): Type {
|
function getTypeOfAccessors(symbol: Symbol): Type {
|
||||||
const links = getSymbolLinks(symbol);
|
const links = getSymbolLinks(symbol);
|
||||||
if (!links.type) {
|
if (!links.type) {
|
||||||
|
@ -4361,20 +4376,12 @@ namespace ts {
|
||||||
function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature {
|
function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature {
|
||||||
const links = getNodeLinks(declaration);
|
const links = getNodeLinks(declaration);
|
||||||
if (!links.resolvedSignature) {
|
if (!links.resolvedSignature) {
|
||||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
|
||||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
|
||||||
: undefined;
|
|
||||||
const typeParameters = classType ? classType.localTypeParameters :
|
|
||||||
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
|
|
||||||
getTypeParametersFromJSDocTemplate(declaration);
|
|
||||||
const parameters: Symbol[] = [];
|
const parameters: Symbol[] = [];
|
||||||
let hasStringLiterals = false;
|
let hasStringLiterals = false;
|
||||||
let minArgumentCount = -1;
|
let minArgumentCount = -1;
|
||||||
let thisType: Type = undefined;
|
let thisType: Type = undefined;
|
||||||
let hasThisParameter: boolean;
|
let hasThisParameter: boolean;
|
||||||
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
||||||
let returnType: Type = undefined;
|
|
||||||
let typePredicate: TypePredicate = undefined;
|
|
||||||
|
|
||||||
// If this is a JSDoc construct signature, then skip the first parameter in the
|
// If this is a JSDoc construct signature, then skip the first parameter in the
|
||||||
// parameter list. The first parameter represents the return type of the construct
|
// parameter list. The first parameter represents the return type of the construct
|
||||||
|
@ -4411,48 +4418,68 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
|
||||||
|
if ((declaration.kind === SyntaxKind.GetAccessor || declaration.kind === SyntaxKind.SetAccessor) &&
|
||||||
|
!hasDynamicName(declaration) &&
|
||||||
|
(!hasThisParameter || thisType === unknownType)) {
|
||||||
|
const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
|
||||||
|
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, otherKind);
|
||||||
|
thisType = getAnnotatedAccessorThisType(setter);
|
||||||
|
}
|
||||||
|
|
||||||
if (minArgumentCount < 0) {
|
if (minArgumentCount < 0) {
|
||||||
minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0);
|
minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isJSConstructSignature) {
|
if (isJSConstructSignature) {
|
||||||
minArgumentCount--;
|
minArgumentCount--;
|
||||||
returnType = getTypeFromTypeNode(declaration.parameters[0].type);
|
|
||||||
}
|
}
|
||||||
else if (classType) {
|
|
||||||
returnType = classType;
|
|
||||||
}
|
|
||||||
else if (declaration.type) {
|
|
||||||
returnType = getTypeFromTypeNode(declaration.type);
|
|
||||||
if (declaration.type.kind === SyntaxKind.TypePredicate) {
|
|
||||||
typePredicate = createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
|
||||||
const type = getReturnTypeFromJSDocComment(declaration);
|
|
||||||
if (type && type !== unknownType) {
|
|
||||||
returnType = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypeScript 1.0 spec (April 2014):
|
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||||
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
|
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||||
if (declaration.kind === SyntaxKind.GetAccessor && !hasDynamicName(declaration)) {
|
: undefined;
|
||||||
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, SyntaxKind.SetAccessor);
|
const typeParameters = classType ? classType.localTypeParameters :
|
||||||
returnType = getAnnotatedAccessorType(setter);
|
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
|
||||||
}
|
getTypeParametersFromJSDocTemplate(declaration);
|
||||||
|
const returnType = getSignatureReturnTypeFromDeclaration(declaration, minArgumentCount, isJSConstructSignature, classType);
|
||||||
if (!returnType && nodeIsMissing((<FunctionLikeDeclaration>declaration).body)) {
|
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
|
||||||
returnType = anyType;
|
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
|
||||||
}
|
undefined;
|
||||||
}
|
|
||||||
|
|
||||||
links.resolvedSignature = createSignature(declaration, typeParameters, thisType, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
links.resolvedSignature = createSignature(declaration, typeParameters, thisType, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
||||||
}
|
}
|
||||||
return links.resolvedSignature;
|
return links.resolvedSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, minArgumentCount: number, isJSConstructSignature: boolean, classType: Type) {
|
||||||
|
if (isJSConstructSignature) {
|
||||||
|
return getTypeFromTypeNode(declaration.parameters[0].type);
|
||||||
|
}
|
||||||
|
else if (classType) {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
else if (declaration.type) {
|
||||||
|
return getTypeFromTypeNode(declaration.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
||||||
|
const type = getReturnTypeFromJSDocComment(declaration);
|
||||||
|
if (type && type !== unknownType) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeScript 1.0 spec (April 2014):
|
||||||
|
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
|
||||||
|
if (declaration.kind === SyntaxKind.GetAccessor && !hasDynamicName(declaration)) {
|
||||||
|
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, SyntaxKind.SetAccessor);
|
||||||
|
return getAnnotatedAccessorType(setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeIsMissing((<FunctionLikeDeclaration>declaration).body)) {
|
||||||
|
return anyType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getSignaturesOfSymbol(symbol: Symbol): Signature[] {
|
function getSignaturesOfSymbol(symbol: Symbol): Signature[] {
|
||||||
if (!symbol) return emptyArray;
|
if (!symbol) return emptyArray;
|
||||||
const result: Signature[] = [];
|
const result: Signature[] = [];
|
||||||
|
@ -12644,9 +12671,6 @@ namespace ts {
|
||||||
if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) {
|
if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) {
|
||||||
error(node, Diagnostics.A_constructor_cannot_have_a_this_parameter);
|
error(node, Diagnostics.A_constructor_cannot_have_a_this_parameter);
|
||||||
}
|
}
|
||||||
if (func.kind === SyntaxKind.SetAccessor) {
|
|
||||||
error(node, Diagnostics.A_setter_cannot_have_a_this_parameter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only check rest parameter type if it's not a binding pattern. Since binding patterns are
|
// Only check rest parameter type if it's not a binding pattern. Since binding patterns are
|
||||||
|
@ -13033,15 +13057,10 @@ namespace ts {
|
||||||
error(node.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
|
error(node.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentAccessorType = getAnnotatedAccessorType(node);
|
|
||||||
const otherAccessorType = getAnnotatedAccessorType(otherAccessor);
|
|
||||||
// TypeScript 1.0 spec (April 2014): 4.5
|
// TypeScript 1.0 spec (April 2014): 4.5
|
||||||
// If both accessors include type annotations, the specified types must be identical.
|
// If both accessors include type annotations, the specified types must be identical.
|
||||||
if (currentAccessorType && otherAccessorType) {
|
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, Diagnostics.get_and_set_accessor_must_have_the_same_type);
|
||||||
if (!isTypeIdenticalTo(currentAccessorType, otherAccessorType)) {
|
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorThisType, Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
|
||||||
error(node, Diagnostics.get_and_set_accessor_must_have_the_same_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getTypeOfAccessors(getSymbolOfNode(node));
|
getTypeOfAccessors(getSymbolOfNode(node));
|
||||||
|
@ -13054,6 +13073,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkAccessorDeclarationTypesIdentical(first: AccessorDeclaration, second: AccessorDeclaration, getAnnotatedType: (a: AccessorDeclaration) => Type, message: DiagnosticMessage) {
|
||||||
|
const firstType = getAnnotatedType(first);
|
||||||
|
const secondType = getAnnotatedType(second);
|
||||||
|
if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
|
||||||
|
error(first, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkAccessorDeferred(node: AccessorDeclaration) {
|
function checkAccessorDeferred(node: AccessorDeclaration) {
|
||||||
checkSourceElement(node.body);
|
checkSourceElement(node.body);
|
||||||
}
|
}
|
||||||
|
@ -18127,7 +18154,7 @@ namespace ts {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkGrammarAccessor(accessor: MethodDeclaration): boolean {
|
function checkGrammarAccessor(accessor: AccessorDeclaration): boolean {
|
||||||
const kind = accessor.kind;
|
const kind = accessor.kind;
|
||||||
if (languageVersion < ScriptTarget.ES5) {
|
if (languageVersion < ScriptTarget.ES5) {
|
||||||
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
|
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
|
||||||
|
@ -18141,16 +18168,16 @@ namespace ts {
|
||||||
else if (accessor.typeParameters) {
|
else if (accessor.typeParameters) {
|
||||||
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
|
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
|
||||||
}
|
}
|
||||||
else if (kind === SyntaxKind.GetAccessor && accessor.parameters.length) {
|
else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
|
||||||
return grammarErrorOnNode(accessor.name, Diagnostics.A_get_accessor_cannot_have_parameters);
|
return grammarErrorOnNode(accessor.name,
|
||||||
|
kind === SyntaxKind.GetAccessor ?
|
||||||
|
Diagnostics.A_get_accessor_cannot_have_parameters :
|
||||||
|
Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
|
||||||
}
|
}
|
||||||
else if (kind === SyntaxKind.SetAccessor) {
|
else if (kind === SyntaxKind.SetAccessor) {
|
||||||
if (accessor.type) {
|
if (accessor.type) {
|
||||||
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
|
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
|
||||||
}
|
}
|
||||||
else if (accessor.parameters.length !== 1) {
|
|
||||||
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
const parameter = accessor.parameters[0];
|
const parameter = accessor.parameters[0];
|
||||||
if (parameter.dotDotDotToken) {
|
if (parameter.dotDotDotToken) {
|
||||||
|
@ -18169,6 +18196,22 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Does the accessor have the right number of parameters?
|
||||||
|
|
||||||
|
A get accessor has no parameters or a single `this` parameter.
|
||||||
|
A set accessor has one parameter or a `this` parameter and one more parameter */
|
||||||
|
function doesAccessorHaveCorrectParameterCount(accessor: AccessorDeclaration) {
|
||||||
|
return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAccessorThisParameter(accessor: AccessorDeclaration) {
|
||||||
|
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
|
||||||
|
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||||
|
(<Identifier>accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
|
||||||
|
return accessor.parameters[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
|
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
|
||||||
if (isDynamicName(node)) {
|
if (isDynamicName(node)) {
|
||||||
return grammarErrorOnNode(node, message);
|
return grammarErrorOnNode(node, message);
|
||||||
|
|
|
@ -1907,7 +1907,7 @@
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 2681
|
"code": 2681
|
||||||
},
|
},
|
||||||
"A setter cannot have a 'this' parameter.": {
|
"'get' and 'set' accessor must have the same 'this' type.": {
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 2682
|
"code": 2682
|
||||||
},
|
},
|
||||||
|
|
|
@ -2269,7 +2269,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
|
export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
|
||||||
return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type;
|
if (accessor && accessor.parameters.length > 0) {
|
||||||
|
const hasThis = accessor.parameters.length === 2 &&
|
||||||
|
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||||
|
(accessor.parameters[0].name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||||
|
return accessor.parameters[hasThis ? 1 : 0].type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllAccessorDeclarations(declarations: NodeArray<Declaration>, accessor: AccessorDeclaration) {
|
export function getAllAccessorDeclarations(declarations: NodeArray<Declaration>, accessor: AccessorDeclaration) {
|
||||||
|
|
83
tests/baselines/reference/thisTypeInAccessors.js
Normal file
83
tests/baselines/reference/thisTypeInAccessors.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
//// [thisTypeInAccessors.ts]
|
||||||
|
interface Foo {
|
||||||
|
n: number;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const explicit = {
|
||||||
|
n: 12,
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromGetter = {
|
||||||
|
n: 14,
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromSetter = {
|
||||||
|
n: 15,
|
||||||
|
get x() { return this.n },
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromGetterUnannotated = {
|
||||||
|
n: 16,
|
||||||
|
get x(this: Foo) { return this.n },
|
||||||
|
set x(this, n) { this.n = n; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Explicit {
|
||||||
|
n = 17;
|
||||||
|
get x(this: Foo): number { return this.n; }
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
class Contextual {
|
||||||
|
n = 21;
|
||||||
|
get x() { return this.n } // inside a class, so already correct
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [thisTypeInAccessors.js]
|
||||||
|
var explicit = {
|
||||||
|
n: 12,
|
||||||
|
get x() { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
};
|
||||||
|
var copiedFromGetter = {
|
||||||
|
n: 14,
|
||||||
|
get x() { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
};
|
||||||
|
var copiedFromSetter = {
|
||||||
|
n: 15,
|
||||||
|
get x() { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
};
|
||||||
|
var copiedFromGetterUnannotated = {
|
||||||
|
n: 16,
|
||||||
|
get x() { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
};
|
||||||
|
var Explicit = (function () {
|
||||||
|
function Explicit() {
|
||||||
|
this.n = 17;
|
||||||
|
}
|
||||||
|
Object.defineProperty(Explicit.prototype, "x", {
|
||||||
|
get: function () { return this.n; },
|
||||||
|
set: function (n) { this.n = n; },
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
return Explicit;
|
||||||
|
}());
|
||||||
|
var Contextual = (function () {
|
||||||
|
function Contextual() {
|
||||||
|
this.n = 21;
|
||||||
|
}
|
||||||
|
Object.defineProperty(Contextual.prototype, "x", {
|
||||||
|
get: function () { return this.n; } // inside a class, so already correct
|
||||||
|
,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
return Contextual;
|
||||||
|
}());
|
140
tests/baselines/reference/thisTypeInAccessors.symbols
Normal file
140
tests/baselines/reference/thisTypeInAccessors.symbols
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
=== tests/cases/conformance/types/thisType/thisTypeInAccessors.ts ===
|
||||||
|
interface Foo {
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
|
||||||
|
n: number;
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
x: number;
|
||||||
|
>x : Symbol(Foo.x, Decl(thisTypeInAccessors.ts, 1, 14))
|
||||||
|
}
|
||||||
|
|
||||||
|
const explicit = {
|
||||||
|
>explicit : Symbol(explicit, Decl(thisTypeInAccessors.ts, 5, 5))
|
||||||
|
|
||||||
|
n: 12,
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 5, 18))
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 6, 10), Decl(thisTypeInAccessors.ts, 7, 48))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 7, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 6, 10), Decl(thisTypeInAccessors.ts, 7, 48))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 8, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 8, 20))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 8, 20))
|
||||||
|
}
|
||||||
|
const copiedFromGetter = {
|
||||||
|
>copiedFromGetter : Symbol(copiedFromGetter, Decl(thisTypeInAccessors.ts, 10, 5))
|
||||||
|
|
||||||
|
n: 14,
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 10, 26))
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 11, 10), Decl(thisTypeInAccessors.ts, 12, 48))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 12, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 11, 10), Decl(thisTypeInAccessors.ts, 12, 48))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 13, 10))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 13, 10))
|
||||||
|
}
|
||||||
|
const copiedFromSetter = {
|
||||||
|
>copiedFromSetter : Symbol(copiedFromSetter, Decl(thisTypeInAccessors.ts, 15, 5))
|
||||||
|
|
||||||
|
n: 15,
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 15, 26))
|
||||||
|
|
||||||
|
get x() { return this.n },
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 16, 10), Decl(thisTypeInAccessors.ts, 17, 30))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 16, 10), Decl(thisTypeInAccessors.ts, 17, 30))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 18, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 18, 20))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 18, 20))
|
||||||
|
}
|
||||||
|
const copiedFromGetterUnannotated = {
|
||||||
|
>copiedFromGetterUnannotated : Symbol(copiedFromGetterUnannotated, Decl(thisTypeInAccessors.ts, 20, 5))
|
||||||
|
|
||||||
|
n: 16,
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 20, 37))
|
||||||
|
|
||||||
|
get x(this: Foo) { return this.n },
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 21, 10), Decl(thisTypeInAccessors.ts, 22, 39))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 22, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
set x(this, n) { this.n = n; }
|
||||||
|
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 21, 10), Decl(thisTypeInAccessors.ts, 22, 39))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 23, 10))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 23, 15))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 23, 15))
|
||||||
|
}
|
||||||
|
|
||||||
|
class Explicit {
|
||||||
|
>Explicit : Symbol(Explicit, Decl(thisTypeInAccessors.ts, 24, 1))
|
||||||
|
|
||||||
|
n = 17;
|
||||||
|
>n : Symbol(Explicit.n, Decl(thisTypeInAccessors.ts, 26, 16))
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; }
|
||||||
|
>x : Symbol(Explicit.x, Decl(thisTypeInAccessors.ts, 27, 11), Decl(thisTypeInAccessors.ts, 28, 47))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 28, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : Symbol(Explicit.x, Decl(thisTypeInAccessors.ts, 27, 11), Decl(thisTypeInAccessors.ts, 28, 47))
|
||||||
|
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 29, 10))
|
||||||
|
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 29, 20))
|
||||||
|
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
|
||||||
|
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
|
||||||
|
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 29, 20))
|
||||||
|
}
|
||||||
|
class Contextual {
|
||||||
|
>Contextual : Symbol(Contextual, Decl(thisTypeInAccessors.ts, 30, 1))
|
||||||
|
|
||||||
|
n = 21;
|
||||||
|
>n : Symbol(Contextual.n, Decl(thisTypeInAccessors.ts, 31, 18))
|
||||||
|
|
||||||
|
get x() { return this.n } // inside a class, so already correct
|
||||||
|
>x : Symbol(Contextual.x, Decl(thisTypeInAccessors.ts, 32, 11))
|
||||||
|
>this.n : Symbol(Contextual.n, Decl(thisTypeInAccessors.ts, 31, 18))
|
||||||
|
>this : Symbol(Contextual, Decl(thisTypeInAccessors.ts, 30, 1))
|
||||||
|
>n : Symbol(Contextual.n, Decl(thisTypeInAccessors.ts, 31, 18))
|
||||||
|
}
|
||||||
|
|
155
tests/baselines/reference/thisTypeInAccessors.types
Normal file
155
tests/baselines/reference/thisTypeInAccessors.types
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
=== tests/cases/conformance/types/thisType/thisTypeInAccessors.ts ===
|
||||||
|
interface Foo {
|
||||||
|
>Foo : Foo
|
||||||
|
|
||||||
|
n: number;
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
x: number;
|
||||||
|
>x : number
|
||||||
|
}
|
||||||
|
|
||||||
|
const explicit = {
|
||||||
|
>explicit : { n: number; x: number; }
|
||||||
|
>{ n: 12, get x(this: Foo): number { return this.n; }, set x(this: Foo, n: number) { this.n = n; }} : { n: number; x: number; }
|
||||||
|
|
||||||
|
n: 12,
|
||||||
|
>n : number
|
||||||
|
>12 : number
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>n : number
|
||||||
|
>this.n = n : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
const copiedFromGetter = {
|
||||||
|
>copiedFromGetter : { n: number; x: number; }
|
||||||
|
>{ n: 14, get x(this: Foo): number { return this.n; }, set x(n) { this.n = n; }} : { n: number; x: number; }
|
||||||
|
|
||||||
|
n: 14,
|
||||||
|
>n : number
|
||||||
|
>14 : number
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
>x : number
|
||||||
|
>n : number
|
||||||
|
>this.n = n : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
const copiedFromSetter = {
|
||||||
|
>copiedFromSetter : { n: number; x: number; }
|
||||||
|
>{ n: 15, get x() { return this.n }, set x(this: Foo, n: number) { this.n = n; }} : { n: number; x: number; }
|
||||||
|
|
||||||
|
n: 15,
|
||||||
|
>n : number
|
||||||
|
>15 : number
|
||||||
|
|
||||||
|
get x() { return this.n },
|
||||||
|
>x : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>n : number
|
||||||
|
>this.n = n : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
const copiedFromGetterUnannotated = {
|
||||||
|
>copiedFromGetterUnannotated : { n: number; x: number; }
|
||||||
|
>{ n: 16, get x(this: Foo) { return this.n }, set x(this, n) { this.n = n; }} : { n: number; x: number; }
|
||||||
|
|
||||||
|
n: 16,
|
||||||
|
>n : number
|
||||||
|
>16 : number
|
||||||
|
|
||||||
|
get x(this: Foo) { return this.n },
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
set x(this, n) { this.n = n; }
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>this.n = n : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
|
||||||
|
class Explicit {
|
||||||
|
>Explicit : Explicit
|
||||||
|
|
||||||
|
n = 17;
|
||||||
|
>n : number
|
||||||
|
>17 : number
|
||||||
|
|
||||||
|
get x(this: Foo): number { return this.n; }
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
>x : number
|
||||||
|
>this : Foo
|
||||||
|
>Foo : Foo
|
||||||
|
>n : number
|
||||||
|
>this.n = n : number
|
||||||
|
>this.n : number
|
||||||
|
>this : Foo
|
||||||
|
>n : number
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
class Contextual {
|
||||||
|
>Contextual : Contextual
|
||||||
|
|
||||||
|
n = 21;
|
||||||
|
>n : number
|
||||||
|
>21 : number
|
||||||
|
|
||||||
|
get x() { return this.n } // inside a class, so already correct
|
||||||
|
>x : number
|
||||||
|
>this.n : number
|
||||||
|
>this : this
|
||||||
|
>n : number
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(10,9): error TS2682: 'get' and 'set' accessor must have the same 'this' type.
|
||||||
|
tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(11,9): error TS2682: 'get' and 'set' accessor must have the same 'this' type.
|
||||||
|
tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(16,22): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts (3 errors) ====
|
||||||
|
interface Foo {
|
||||||
|
n: number;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
interface Bar {
|
||||||
|
wrong: "place" | "time" | "method" | "technique";
|
||||||
|
}
|
||||||
|
const mismatch = {
|
||||||
|
n: 13,
|
||||||
|
get x(this: Foo) { return this.n; },
|
||||||
|
~
|
||||||
|
!!! error TS2682: 'get' and 'set' accessor must have the same 'this' type.
|
||||||
|
set x(this: Bar, n) { this.wrong = "method"; }
|
||||||
|
~
|
||||||
|
!!! error TS2682: 'get' and 'set' accessor must have the same 'this' type.
|
||||||
|
}
|
||||||
|
const contextual: Foo = {
|
||||||
|
n: 16,
|
||||||
|
// there is no contextual this type from an Foo.x.
|
||||||
|
get x() { return this.n; }
|
||||||
|
~~~~
|
||||||
|
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||||
|
}
|
||||||
|
|
31
tests/baselines/reference/thisTypeInAccessorsNegative.js
Normal file
31
tests/baselines/reference/thisTypeInAccessorsNegative.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//// [thisTypeInAccessorsNegative.ts]
|
||||||
|
interface Foo {
|
||||||
|
n: number;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
interface Bar {
|
||||||
|
wrong: "place" | "time" | "method" | "technique";
|
||||||
|
}
|
||||||
|
const mismatch = {
|
||||||
|
n: 13,
|
||||||
|
get x(this: Foo) { return this.n; },
|
||||||
|
set x(this: Bar, n) { this.wrong = "method"; }
|
||||||
|
}
|
||||||
|
const contextual: Foo = {
|
||||||
|
n: 16,
|
||||||
|
// there is no contextual this type from an Foo.x.
|
||||||
|
get x() { return this.n; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [thisTypeInAccessorsNegative.js]
|
||||||
|
var mismatch = {
|
||||||
|
n: 13,
|
||||||
|
get x() { return this.n; },
|
||||||
|
set x(n) { this.wrong = "method"; }
|
||||||
|
};
|
||||||
|
var contextual = {
|
||||||
|
n: 16,
|
||||||
|
// there is no contextual this type from an Foo.x.
|
||||||
|
get x() { return this.n; }
|
||||||
|
};
|
|
@ -75,32 +75,31 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(146,1): er
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(148,1): error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(148,1): error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(154,16): error TS2679: A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(154,16): error TS2679: A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(158,17): error TS2681: A constructor cannot have a 'this' parameter.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(158,17): error TS2681: A constructor cannot have a 'this' parameter.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(160,11): error TS2682: A setter cannot have a 'this' parameter.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(162,9): error TS2681: A constructor cannot have a 'this' parameter.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(164,9): error TS2681: A constructor cannot have a 'this' parameter.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(164,31): error TS2681: A constructor cannot have a 'this' parameter.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(166,31): error TS2681: A constructor cannot have a 'this' parameter.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(165,30): error TS2680: A 'this' parameter must be the first parameter.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(167,30): error TS2680: A 'this' parameter must be the first parameter.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(168,26): error TS1003: Identifier expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,26): error TS1003: Identifier expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(168,30): error TS1005: ',' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,30): error TS1005: ',' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(169,20): error TS2370: A rest parameter must be of an array type.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,20): error TS2370: A rest parameter must be of an array type.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(169,23): error TS1003: Identifier expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,23): error TS1003: Identifier expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(169,27): error TS1005: ',' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,27): error TS1005: ',' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,23): error TS1005: ',' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,23): error TS1005: ',' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,24): error TS1138: Parameter declaration expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,24): error TS1138: Parameter declaration expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,28): error TS1003: Identifier expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(173,28): error TS1003: Identifier expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,32): error TS1005: ',' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(173,32): error TS1005: ',' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,30): error TS1005: ',' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,30): error TS1005: ',' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,32): error TS1138: Parameter declaration expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,32): error TS1138: Parameter declaration expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,39): error TS1005: ';' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,39): error TS1005: ';' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,40): error TS1128: Declaration or statement expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,40): error TS1128: Declaration or statement expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,42): error TS2304: Cannot find name 'number'.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,42): error TS2304: Cannot find name 'number'.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,49): error TS1005: ';' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(174,49): error TS1005: ';' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,1): error TS7027: Unreachable code detected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,1): error TS7027: Unreachable code detected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,29): error TS2304: Cannot find name 'm'.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,29): error TS2304: Cannot find name 'm'.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,32): error TS1005: ';' expected.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,32): error TS1005: ';' expected.
|
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,35): error TS2304: Cannot find name 'm'.
|
||||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,35): error TS2304: Cannot find name 'm'.
|
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (66 errors) ====
|
==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (65 errors) ====
|
||||||
class C {
|
class C {
|
||||||
n: number;
|
n: number;
|
||||||
explicitThis(this: this, m: number): number {
|
explicitThis(this: this, m: number): number {
|
||||||
|
@ -380,10 +379,6 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,35): e
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
!!! error TS2681: A constructor cannot have a 'this' parameter.
|
!!! error TS2681: A constructor cannot have a 'this' parameter.
|
||||||
}
|
}
|
||||||
set p(this: void) {
|
|
||||||
~~~~~~~~~~
|
|
||||||
!!! error TS2682: A setter cannot have a 'this' parameter.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
interface ThisConstructorInterface {
|
interface ThisConstructorInterface {
|
||||||
new(this: ThisConstructor, n: number);
|
new(this: ThisConstructor, n: number);
|
||||||
|
|
|
@ -158,8 +158,6 @@ let voidThis = new VoidThis();
|
||||||
class ThisConstructor {
|
class ThisConstructor {
|
||||||
constructor(this: ThisConstructor, private n: number) {
|
constructor(this: ThisConstructor, private n: number) {
|
||||||
}
|
}
|
||||||
set p(this: void) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
interface ThisConstructorInterface {
|
interface ThisConstructorInterface {
|
||||||
new(this: ThisConstructor, n: number);
|
new(this: ThisConstructor, n: number);
|
||||||
|
@ -332,12 +330,6 @@ var ThisConstructor = (function () {
|
||||||
function ThisConstructor(n) {
|
function ThisConstructor(n) {
|
||||||
this.n = n;
|
this.n = n;
|
||||||
}
|
}
|
||||||
Object.defineProperty(ThisConstructor.prototype, "p", {
|
|
||||||
set: function () {
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
return ThisConstructor;
|
return ThisConstructor;
|
||||||
}());
|
}());
|
||||||
var thisConstructorType;
|
var thisConstructorType;
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// @noImplicitAny: true
|
||||||
|
// @noImplicitThis: true
|
||||||
|
// @target: es5
|
||||||
|
interface Foo {
|
||||||
|
n: number;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const explicit = {
|
||||||
|
n: 12,
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromGetter = {
|
||||||
|
n: 14,
|
||||||
|
get x(this: Foo): number { return this.n; },
|
||||||
|
set x(n) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromSetter = {
|
||||||
|
n: 15,
|
||||||
|
get x() { return this.n },
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
const copiedFromGetterUnannotated = {
|
||||||
|
n: 16,
|
||||||
|
get x(this: Foo) { return this.n },
|
||||||
|
set x(this, n) { this.n = n; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Explicit {
|
||||||
|
n = 17;
|
||||||
|
get x(this: Foo): number { return this.n; }
|
||||||
|
set x(this: Foo, n: number) { this.n = n; }
|
||||||
|
}
|
||||||
|
class Contextual {
|
||||||
|
n = 21;
|
||||||
|
get x() { return this.n } // inside a class, so already correct
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// @noImplicitAny: true
|
||||||
|
// @noImplicitThis: true
|
||||||
|
// @target: es5
|
||||||
|
interface Foo {
|
||||||
|
n: number;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
interface Bar {
|
||||||
|
wrong: "place" | "time" | "method" | "technique";
|
||||||
|
}
|
||||||
|
const mismatch = {
|
||||||
|
n: 13,
|
||||||
|
get x(this: Foo) { return this.n; },
|
||||||
|
set x(this: Bar, n) { this.wrong = "method"; }
|
||||||
|
}
|
||||||
|
const contextual: Foo = {
|
||||||
|
n: 16,
|
||||||
|
// there is no contextual this type from an Foo.x.
|
||||||
|
get x() { return this.n; }
|
||||||
|
}
|
|
@ -157,8 +157,6 @@ let voidThis = new VoidThis();
|
||||||
class ThisConstructor {
|
class ThisConstructor {
|
||||||
constructor(this: ThisConstructor, private n: number) {
|
constructor(this: ThisConstructor, private n: number) {
|
||||||
}
|
}
|
||||||
set p(this: void) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
interface ThisConstructorInterface {
|
interface ThisConstructorInterface {
|
||||||
new(this: ThisConstructor, n: number);
|
new(this: ThisConstructor, n: number);
|
||||||
|
|
Loading…
Reference in a new issue