Skip to content

Commit d9b5a75

Browse files
authored
Make anyFunctionType a subtype of all function types (#1149)
1 parent 9cf6764 commit d9b5a75

File tree

5 files changed

+117
-10
lines changed

5 files changed

+117
-10
lines changed

internal/checker/relater.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4360,9 +4360,13 @@ func (r *Relater) signaturesRelatedTo(source *Type, target *Type, kind Signature
43604360
if r.relation == r.c.identityRelation {
43614361
return r.signaturesIdenticalTo(source, target, kind)
43624362
}
4363-
if target == r.c.anyFunctionType || r.relation != r.c.strictSubtypeRelation && source == r.c.anyFunctionType {
4363+
// With respect to signatures, the anyFunctionType wildcard is a subtype of every other function type.
4364+
if source == r.c.anyFunctionType {
43644365
return TernaryTrue
43654366
}
4367+
if target == r.c.anyFunctionType {
4368+
return TernaryFalse
4369+
}
43664370
sourceSignatures := r.c.getSignaturesOfType(source, kind)
43674371
targetSignatures := r.c.getSignaturesOfType(target, kind)
43684372
if kind == SignatureKindConstruct && len(sourceSignatures) != 0 && len(targetSignatures) != 0 {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
subtypeReductionWithAnyFunctionType.ts(10,16): error TS7006: Parameter 'x' implicitly has an 'any' type.
2+
3+
4+
==== subtypeReductionWithAnyFunctionType.ts (1 errors) ====
5+
// https://github.com/microsoft/typescript-go/issues/849
6+
7+
declare function useMemo<T>(func: () => T): T;
8+
9+
function getPredicate(alwaysTrue: boolean) {
10+
const predicate: (input: string) => boolean = useMemo(() => {
11+
if (alwaysTrue) {
12+
return () => true;
13+
}
14+
return x => x.length > 0;
15+
~
16+
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
17+
});
18+
return predicate;
19+
}
20+
21+
// https://github.com/microsoft/typescript-go/issues/1016
22+
23+
declare function compact<T>(array: T[]): T[];
24+
declare function makeFooer(): Fooer;
25+
interface Fooer {
26+
foo: (v: string) => string;
27+
}
28+
function f() {
29+
const _ = compact([makeFooer(), { foo: (v) => v }]);
30+
}
31+

testdata/baselines/reference/compiler/subtypeReductionWithAnyFunctionType.symbols

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,42 @@ function getPredicate(alwaysTrue: boolean) {
2626
}
2727
return x => x.length > 0;
2828
>x : Symbol(x, Decl(subtypeReductionWithAnyFunctionType.ts, 9, 14))
29-
>x.length : Symbol(length, Decl(lib.es5.d.ts, --, --))
3029
>x : Symbol(x, Decl(subtypeReductionWithAnyFunctionType.ts, 9, 14))
31-
>length : Symbol(length, Decl(lib.es5.d.ts, --, --))
3230

3331
});
3432
return predicate;
3533
>predicate : Symbol(predicate, Decl(subtypeReductionWithAnyFunctionType.ts, 5, 9))
3634
}
3735

36+
// https://github.com/microsoft/typescript-go/issues/1016
37+
38+
declare function compact<T>(array: T[]): T[];
39+
>compact : Symbol(compact, Decl(subtypeReductionWithAnyFunctionType.ts, 12, 1))
40+
>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25))
41+
>array : Symbol(array, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 28))
42+
>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25))
43+
>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25))
44+
45+
declare function makeFooer(): Fooer;
46+
>makeFooer : Symbol(makeFooer, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 45))
47+
>Fooer : Symbol(Fooer, Decl(subtypeReductionWithAnyFunctionType.ts, 17, 36))
48+
49+
interface Fooer {
50+
>Fooer : Symbol(Fooer, Decl(subtypeReductionWithAnyFunctionType.ts, 17, 36))
51+
52+
foo: (v: string) => string;
53+
>foo : Symbol(foo, Decl(subtypeReductionWithAnyFunctionType.ts, 18, 17))
54+
>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 19, 10))
55+
}
56+
function f() {
57+
>f : Symbol(f, Decl(subtypeReductionWithAnyFunctionType.ts, 20, 1))
58+
59+
const _ = compact([makeFooer(), { foo: (v) => v }]);
60+
>_ : Symbol(_, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 9))
61+
>compact : Symbol(compact, Decl(subtypeReductionWithAnyFunctionType.ts, 12, 1))
62+
>makeFooer : Symbol(makeFooer, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 45))
63+
>foo : Symbol(foo, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 37))
64+
>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 44))
65+
>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 44))
66+
}
67+

testdata/baselines/reference/compiler/subtypeReductionWithAnyFunctionType.types

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ function getPredicate(alwaysTrue: boolean) {
1414
const predicate: (input: string) => boolean = useMemo(() => {
1515
>predicate : (input: string) => boolean
1616
>input : string
17-
>useMemo(() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; }) : (x: string) => boolean
17+
>useMemo(() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; }) : (x: any) => boolean
1818
>useMemo : <T>(func: () => T) => T
19-
>() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; } : () => (x: string) => boolean
19+
>() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; } : () => (x: any) => boolean
2020

2121
if (alwaysTrue) {
2222
>alwaysTrue : boolean
@@ -26,16 +26,47 @@ function getPredicate(alwaysTrue: boolean) {
2626
>true : true
2727
}
2828
return x => x.length > 0;
29-
>x => x.length > 0 : (x: string) => boolean
30-
>x : string
29+
>x => x.length > 0 : (x: any) => boolean
30+
>x : any
3131
>x.length > 0 : boolean
32-
>x.length : number
33-
>x : string
34-
>length : number
32+
>x.length : any
33+
>x : any
34+
>length : any
3535
>0 : 0
3636

3737
});
3838
return predicate;
3939
>predicate : (input: string) => boolean
4040
}
4141

42+
// https://github.com/microsoft/typescript-go/issues/1016
43+
44+
declare function compact<T>(array: T[]): T[];
45+
>compact : <T>(array: T[]) => T[]
46+
>array : T[]
47+
48+
declare function makeFooer(): Fooer;
49+
>makeFooer : () => Fooer
50+
51+
interface Fooer {
52+
foo: (v: string) => string;
53+
>foo : (v: string) => string
54+
>v : string
55+
}
56+
function f() {
57+
>f : () => void
58+
59+
const _ = compact([makeFooer(), { foo: (v) => v }]);
60+
>_ : Fooer[]
61+
>compact([makeFooer(), { foo: (v) => v }]) : Fooer[]
62+
>compact : <T>(array: T[]) => T[]
63+
>[makeFooer(), { foo: (v) => v }] : Fooer[]
64+
>makeFooer() : Fooer
65+
>makeFooer : () => Fooer
66+
>{ foo: (v) => v } : { foo: (v: string) => string; }
67+
>foo : (v: string) => string
68+
>(v) => v : (v: string) => string
69+
>v : string
70+
>v : string
71+
}
72+

testdata/tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@ function getPredicate(alwaysTrue: boolean) {
1515
});
1616
return predicate;
1717
}
18+
19+
// https://github.com/microsoft/typescript-go/issues/1016
20+
21+
declare function compact<T>(array: T[]): T[];
22+
declare function makeFooer(): Fooer;
23+
interface Fooer {
24+
foo: (v: string) => string;
25+
}
26+
function f() {
27+
const _ = compact([makeFooer(), { foo: (v) => v }]);
28+
}

0 commit comments

Comments
 (0)