Skip to content

Forbid function assignment to index signatures:any #31102

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

Closed
wants to merge 2 commits into from
Closed
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
5 changes: 4 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13574,7 +13574,10 @@ namespace ts {
return indexTypesIdenticalTo(source, target, kind);
}
const targetInfo = getIndexInfoOfType(target, kind);
if (!targetInfo || targetInfo.type.flags & TypeFlags.Any && !sourceIsPrimitive) {
if (!targetInfo ||
targetInfo.type.flags & TypeFlags.Any && !sourceIsPrimitive &&
getSignaturesOfStructuredType(source, SignatureKind.Call).length === 0 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indexTypesRelatedTo just takes Types as arguments, so this should just be getSignaturesOfType:

Suggested change
getSignaturesOfStructuredType(source, SignatureKind.Call).length === 0 &&
getSignaturesOfType(source, SignatureKind.Call).length === 0 &&

getSignaturesOfStructuredType(source, SignatureKind.Construct).length === 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise:

Suggested change
getSignaturesOfStructuredType(source, SignatureKind.Construct).length === 0) {
getSignaturesOfType(source, SignatureKind.Construct).length === 0) {

// Index signature of type any permits assignment from everything but primitives
return Ternary.True;
}
Expand Down
16 changes: 16 additions & 0 deletions tests/baselines/reference/functionAssignableToArrayLike.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/functionAssignableToArrayLike.ts(1,5): error TS2322: Type '(x: any, y: any) => any' is not assignable to type 'ArrayLike<any>'.
Index signature is missing in type '(x: any, y: any) => any'.
tests/cases/compiler/functionAssignableToArrayLike.ts(2,5): error TS2322: Type '(x: any, y: any) => any' is not assignable to type 'ArrayLike<string>'.
Index signature is missing in type '(x: any, y: any) => any'.


==== tests/cases/compiler/functionAssignableToArrayLike.ts (2 errors) ====
var bad1: ArrayLike<any> = (x, y) => x + y
~~~~
!!! error TS2322: Type '(x: any, y: any) => any' is not assignable to type 'ArrayLike<any>'.
!!! error TS2322: Index signature is missing in type '(x: any, y: any) => any'.
var bad2: ArrayLike<string> = (x, y) => x + y
~~~~
!!! error TS2322: Type '(x: any, y: any) => any' is not assignable to type 'ArrayLike<string>'.
!!! error TS2322: Index signature is missing in type '(x: any, y: any) => any'.

8 changes: 8 additions & 0 deletions tests/baselines/reference/functionAssignableToArrayLike.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [functionAssignableToArrayLike.ts]
var bad1: ArrayLike<any> = (x, y) => x + y
var bad2: ArrayLike<string> = (x, y) => x + y


//// [functionAssignableToArrayLike.js]
var bad1 = function (x, y) { return x + y; };
var bad2 = function (x, y) { return x + y; };
17 changes: 17 additions & 0 deletions tests/baselines/reference/functionAssignableToArrayLike.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
=== tests/cases/compiler/functionAssignableToArrayLike.ts ===
var bad1: ArrayLike<any> = (x, y) => x + y
>bad1 : Symbol(bad1, Decl(functionAssignableToArrayLike.ts, 0, 3))
>ArrayLike : Symbol(ArrayLike, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(functionAssignableToArrayLike.ts, 0, 28))
>y : Symbol(y, Decl(functionAssignableToArrayLike.ts, 0, 30))
>x : Symbol(x, Decl(functionAssignableToArrayLike.ts, 0, 28))
>y : Symbol(y, Decl(functionAssignableToArrayLike.ts, 0, 30))

var bad2: ArrayLike<string> = (x, y) => x + y
>bad2 : Symbol(bad2, Decl(functionAssignableToArrayLike.ts, 1, 3))
>ArrayLike : Symbol(ArrayLike, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(functionAssignableToArrayLike.ts, 1, 31))
>y : Symbol(y, Decl(functionAssignableToArrayLike.ts, 1, 33))
>x : Symbol(x, Decl(functionAssignableToArrayLike.ts, 1, 31))
>y : Symbol(y, Decl(functionAssignableToArrayLike.ts, 1, 33))

19 changes: 19 additions & 0 deletions tests/baselines/reference/functionAssignableToArrayLike.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
=== tests/cases/compiler/functionAssignableToArrayLike.ts ===
var bad1: ArrayLike<any> = (x, y) => x + y
>bad1 : ArrayLike<any>
>(x, y) => x + y : (x: any, y: any) => any
>x : any
>y : any
>x + y : any
>x : any
>y : any

var bad2: ArrayLike<string> = (x, y) => x + y
>bad2 : ArrayLike<string>
>(x, y) => x + y : (x: any, y: any) => any
>x : any
>y : any
>x + y : any
>x : any
>y : any

12 changes: 11 additions & 1 deletion tests/baselines/reference/intTypeCheck.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ tests/cases/compiler/intTypeCheck.ts(134,21): error TS1109: Expression expected.
tests/cases/compiler/intTypeCheck.ts(134,22): error TS2693: 'i3' only refers to a type, but is being used as a value here.
tests/cases/compiler/intTypeCheck.ts(135,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/intTypeCheck.ts(142,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/intTypeCheck.ts(145,5): error TS2322: Type '() => void' is not assignable to type 'i4'.
Index signature is missing in type '() => void'.
tests/cases/compiler/intTypeCheck.ts(148,5): error TS2322: Type 'boolean' is not assignable to type 'i4'.
tests/cases/compiler/intTypeCheck.ts(148,21): error TS1109: Expression expected.
tests/cases/compiler/intTypeCheck.ts(148,22): error TS2693: 'i4' only refers to a type, but is being used as a value here.
Expand Down Expand Up @@ -78,13 +80,15 @@ tests/cases/compiler/intTypeCheck.ts(190,21): error TS1109: Expression expected.
tests/cases/compiler/intTypeCheck.ts(190,22): error TS2693: 'i7' only refers to a type, but is being used as a value here.
tests/cases/compiler/intTypeCheck.ts(191,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/intTypeCheck.ts(198,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/intTypeCheck.ts(201,5): error TS2322: Type '() => void' is not assignable to type 'i8'.
Index signature is missing in type '() => void'.
tests/cases/compiler/intTypeCheck.ts(204,5): error TS2322: Type 'boolean' is not assignable to type 'i8'.
tests/cases/compiler/intTypeCheck.ts(204,21): error TS1109: Expression expected.
tests/cases/compiler/intTypeCheck.ts(204,22): error TS2693: 'i8' only refers to a type, but is being used as a value here.
tests/cases/compiler/intTypeCheck.ts(205,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.


==== tests/cases/compiler/intTypeCheck.ts (63 errors) ====
==== tests/cases/compiler/intTypeCheck.ts (65 errors) ====
interface i1 {
//Property Signatures
p;
Expand Down Expand Up @@ -296,6 +300,9 @@ tests/cases/compiler/intTypeCheck.ts(205,17): error TS2351: Cannot use 'new' wit
var obj37: i4 = new Base;
var obj38: i4 = null;
var obj39: i4 = function () { };
~~~~~
!!! error TS2322: Type '() => void' is not assignable to type 'i4'.
!!! error TS2322: Index signature is missing in type '() => void'.
//var obj40: i4 = function foo() { };
var obj41: i4 = <i4> anyVar;
var obj42: i4 = new <i4> anyVar;
Expand Down Expand Up @@ -425,6 +432,9 @@ tests/cases/compiler/intTypeCheck.ts(205,17): error TS2351: Cannot use 'new' wit
var obj81: i8 = new Base;
var obj82: i8 = null;
var obj83: i8 = function () { };
~~~~~
!!! error TS2322: Type '() => void' is not assignable to type 'i8'.
!!! error TS2322: Index signature is missing in type '() => void'.
//var obj84: i8 = function foo() { };
var obj85: i8 = <i8> anyVar;
var obj86: i8 = new <i8> anyVar;
Expand Down
2 changes: 2 additions & 0 deletions tests/cases/compiler/functionAssignableToArrayLike.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var bad1: ArrayLike<any> = (x, y) => x + y
var bad2: ArrayLike<string> = (x, y) => x + y