Skip to content

Static property conflicts in ambient context #13616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15722,12 +15722,12 @@ namespace ts {
}
}

/**
/**
* Static members being set on a constructor function may conflict with built-in properties
* of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
* built-in properties. This check issues a transpile error when a class has a static
* of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
* built-in properties. This check issues a transpile error when a class has a static
* member with the same name as a non-writable built-in property.
*
*
* @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
* @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
* @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
Expand Down Expand Up @@ -18337,7 +18337,11 @@ namespace ts {
const staticType = <ObjectType>getTypeOfSymbol(symbol);
checkTypeParameterListsIdentical(node, symbol);
checkClassForDuplicateDeclarations(node);
checkClassForStaticPropertyNameConflicts(node);

// Only check for reserved static identifiers on non-ambient context.
if (!isInAmbientContext(node)) {
checkClassForStaticPropertyNameConflicts(node);
}

const baseTypeNode = getClassExtendsHeritageClauseElement(node);
if (baseTypeNode) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts ===

// name
declare class StaticName {
>StaticName : Symbol(StaticName, Decl(decl.d.ts, 0, 0))

static name: number; // ok
>name : Symbol(StaticName.name, Decl(decl.d.ts, 2, 26))

name: string; // ok
>name : Symbol(StaticName.name, Decl(decl.d.ts, 3, 24))
}

declare class StaticNameFn {
>StaticNameFn : Symbol(StaticNameFn, Decl(decl.d.ts, 5, 1))

static name(): string; // ok
>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 7, 28))

name(): string; // ok
>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 8, 26))
}

// length
declare class StaticLength {
>StaticLength : Symbol(StaticLength, Decl(decl.d.ts, 10, 1))

static length: number; // ok
>length : Symbol(StaticLength.length, Decl(decl.d.ts, 13, 28))

length: string; // ok
>length : Symbol(StaticLength.length, Decl(decl.d.ts, 14, 26))
}

declare class StaticLengthFn {
>StaticLengthFn : Symbol(StaticLengthFn, Decl(decl.d.ts, 16, 1))

static length(): number; // ok
>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 18, 30))

length(): number; // ok
>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 19, 28))
}

// prototype
declare class StaticPrototype {
>StaticPrototype : Symbol(StaticPrototype, Decl(decl.d.ts, 21, 1))

static prototype: number; // ok
>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 24, 31))

prototype: string; // ok
>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 25, 29))
}

declare class StaticPrototypeFn {
>StaticPrototypeFn : Symbol(StaticPrototypeFn, Decl(decl.d.ts, 27, 1))

static prototype: any; // ok
>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 29, 33))

prototype(): any; // ok
>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 30, 26))
}

// caller
declare class StaticCaller {
>StaticCaller : Symbol(StaticCaller, Decl(decl.d.ts, 32, 1))

static caller: number; // ok
>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 35, 28))

caller: string; // ok
>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 36, 26))
}

declare class StaticCallerFn {
>StaticCallerFn : Symbol(StaticCallerFn, Decl(decl.d.ts, 38, 1))

static caller(): any; // ok
>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 40, 30))

caller(): any; // ok
>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 41, 25))
}

// arguments
declare class StaticArguments {
>StaticArguments : Symbol(StaticArguments, Decl(decl.d.ts, 43, 1))

static arguments: number; // ok
>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 46, 31))

arguments: string; // ok
>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 47, 29))
}

declare class StaticArgumentsFn {
>StaticArgumentsFn : Symbol(StaticArgumentsFn, Decl(decl.d.ts, 49, 1))

static arguments(): any; // ok
>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 51, 33))

arguments(): any; // ok
>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 52, 28))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts ===

// name
declare class StaticName {
>StaticName : StaticName

static name: number; // ok
>name : number

name: string; // ok
>name : string
}

declare class StaticNameFn {
>StaticNameFn : StaticNameFn

static name(): string; // ok
>name : () => string

name(): string; // ok
>name : () => string
}

// length
declare class StaticLength {
>StaticLength : StaticLength

static length: number; // ok
>length : number

length: string; // ok
>length : string
}

declare class StaticLengthFn {
>StaticLengthFn : StaticLengthFn

static length(): number; // ok
>length : () => number

length(): number; // ok
>length : () => number
}

// prototype
declare class StaticPrototype {
>StaticPrototype : StaticPrototype

static prototype: number; // ok
>prototype : StaticPrototype

prototype: string; // ok
>prototype : string
}

declare class StaticPrototypeFn {
>StaticPrototypeFn : StaticPrototypeFn

static prototype: any; // ok
>prototype : StaticPrototypeFn

prototype(): any; // ok
>prototype : () => any
}

// caller
declare class StaticCaller {
>StaticCaller : StaticCaller

static caller: number; // ok
>caller : number

caller: string; // ok
>caller : string
}

declare class StaticCallerFn {
>StaticCallerFn : StaticCallerFn

static caller(): any; // ok
>caller : () => any

caller(): any; // ok
>caller : () => any
}

// arguments
declare class StaticArguments {
>StaticArguments : StaticArguments

static arguments: number; // ok
>arguments : number

arguments: string; // ok
>arguments : string
}

declare class StaticArgumentsFn {
>StaticArgumentsFn : StaticArgumentsFn

static arguments(): any; // ok
>arguments : () => any

arguments(): any; // ok
>arguments : () => any
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

//@Filename: decl.d.ts
// name
declare class StaticName {
static name: number; // ok
name: string; // ok
}

declare class StaticNameFn {
static name(): string; // ok
name(): string; // ok
}

// length
declare class StaticLength {
static length: number; // ok
length: string; // ok
}

declare class StaticLengthFn {
static length(): number; // ok
length(): number; // ok
}

// prototype
declare class StaticPrototype {
static prototype: number; // ok
prototype: string; // ok
}

declare class StaticPrototypeFn {
static prototype: any; // ok
prototype(): any; // ok
}

// caller
declare class StaticCaller {
static caller: number; // ok
caller: string; // ok
}

declare class StaticCallerFn {
static caller(): any; // ok
caller(): any; // ok
}

// arguments
declare class StaticArguments {
static arguments: number; // ok
arguments: string; // ok
}

declare class StaticArgumentsFn {
static arguments(): any; // ok
arguments(): any; // ok
}