Skip to content

Commit eba78e4

Browse files
committed
use function that doesn't return unknown type
1 parent 5021dd8 commit eba78e4

File tree

5 files changed

+124
-7
lines changed

5 files changed

+124
-7
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10165,11 +10165,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1016510165
return prop ? getTypeOfSymbol(prop) : undefined;
1016610166
}
1016710167

10168-
function getTypeOfPropertyOrIndexSignature(type: Type, name: __String, addOptionalityToIndex: boolean): Type {
10169-
let propType;
10170-
return getTypeOfPropertyOfType(type, name) ||
10171-
(propType = getApplicableIndexInfoForName(type, name)?.type) && addOptionality(propType, /*isProperty*/ true, addOptionalityToIndex) ||
10172-
unknownType;
10168+
function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type {
10169+
return getTypeOfPropertyOfType(type, name) || getApplicableIndexInfoForName(type, name)?.type || unknownType;
1017310170
}
1017410171

1017510172
function isTypeAny(type: Type | undefined) {
@@ -22703,7 +22700,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2270322700
let matched = false;
2270422701
for (let i = 0; i < types.length; i++) {
2270522702
if (include[i]) {
22706-
const targetType = getTypeOfPropertyOrIndexSignature(types[i], propertyName, /*addOptionalityToIndex*/ true);
22703+
const targetType = getTypeOfPropertyOrIndexSignatureOfType(types[i], propertyName);
2270722704
if (targetType && related(getDiscriminatingType(), targetType)) {
2270822705
matched = true;
2270922706
}
@@ -22721,6 +22718,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2272122718
}
2272222719
const filtered = contains(include, Ternary.False) ? getUnionType(types.filter((_, i) => include[i])) : target;
2272322720
return filtered.flags & TypeFlags.Never ? target : filtered;
22721+
22722+
function getTypeOfPropertyOrIndexSignatureOfType(type: Type, name: __String): Type | undefined {
22723+
let propType;
22724+
return getTypeOfPropertyOfType(type, name) ||
22725+
(propType = getApplicableIndexInfoForName(type, name)?.type) &&
22726+
addOptionality(propType, /*isProperty*/ true, /*isOptional*/ true);
22727+
}
2272422728
}
2272522729

2272622730
/**
@@ -27016,7 +27020,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2701627020
propType = removeNullable && optionalChain ? getOptionalType(propType) : propType;
2701727021
const narrowedPropType = narrowType(propType);
2701827022
return filterType(type, t => {
27019-
const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName, /*addOptionalityToIndex*/ false);
27023+
const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName);
2702027024
return !(discriminantType.flags & TypeFlags.Never) && !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType);
2702127025
});
2702227026
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
discriminateWithMissingProperty.ts(12,5): error TS2345: Argument of type '{ mode: "numeric"; data: Uint8Array; }' is not assignable to parameter of type 'Arg'.
2+
Types of property 'data' are incompatible.
3+
Type 'Uint8Array' is not assignable to type 'number'.
4+
5+
6+
==== discriminateWithMissingProperty.ts (1 errors) ====
7+
type Arg = {
8+
mode: "numeric",
9+
data: number,
10+
} | {
11+
mode: "alphabetic",
12+
data: string,
13+
} | {
14+
data: string | Uint8Array;
15+
}
16+
17+
declare function foo(arg: Arg): void;
18+
foo({ mode: "numeric", data: new Uint8Array([30]) }); // Should error
19+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20+
!!! error TS2345: Argument of type '{ mode: "numeric"; data: Uint8Array; }' is not assignable to parameter of type 'Arg'.
21+
!!! error TS2345: Types of property 'data' are incompatible.
22+
!!! error TS2345: Type 'Uint8Array' is not assignable to type 'number'.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/compiler/discriminateWithMissingProperty.ts] ////
2+
3+
=== discriminateWithMissingProperty.ts ===
4+
type Arg = {
5+
>Arg : Symbol(Arg, Decl(discriminateWithMissingProperty.ts, 0, 0))
6+
7+
mode: "numeric",
8+
>mode : Symbol(mode, Decl(discriminateWithMissingProperty.ts, 0, 12))
9+
10+
data: number,
11+
>data : Symbol(data, Decl(discriminateWithMissingProperty.ts, 1, 20))
12+
13+
} | {
14+
mode: "alphabetic",
15+
>mode : Symbol(mode, Decl(discriminateWithMissingProperty.ts, 3, 5))
16+
17+
data: string,
18+
>data : Symbol(data, Decl(discriminateWithMissingProperty.ts, 4, 23))
19+
20+
} | {
21+
data: string | Uint8Array;
22+
>data : Symbol(data, Decl(discriminateWithMissingProperty.ts, 6, 5))
23+
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
24+
}
25+
26+
declare function foo(arg: Arg): void;
27+
>foo : Symbol(foo, Decl(discriminateWithMissingProperty.ts, 8, 1))
28+
>arg : Symbol(arg, Decl(discriminateWithMissingProperty.ts, 10, 21))
29+
>Arg : Symbol(Arg, Decl(discriminateWithMissingProperty.ts, 0, 0))
30+
31+
foo({ mode: "numeric", data: new Uint8Array([30]) }); // Should error
32+
>foo : Symbol(foo, Decl(discriminateWithMissingProperty.ts, 8, 1))
33+
>mode : Symbol(mode, Decl(discriminateWithMissingProperty.ts, 11, 5))
34+
>data : Symbol(data, Decl(discriminateWithMissingProperty.ts, 11, 22))
35+
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
36+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/compiler/discriminateWithMissingProperty.ts] ////
2+
3+
=== discriminateWithMissingProperty.ts ===
4+
type Arg = {
5+
>Arg : { mode: "numeric"; data: number; } | { mode: "alphabetic"; data: string; } | { data: string | Uint8Array; }
6+
7+
mode: "numeric",
8+
>mode : "numeric"
9+
10+
data: number,
11+
>data : number
12+
13+
} | {
14+
mode: "alphabetic",
15+
>mode : "alphabetic"
16+
17+
data: string,
18+
>data : string
19+
20+
} | {
21+
data: string | Uint8Array;
22+
>data : string | Uint8Array
23+
}
24+
25+
declare function foo(arg: Arg): void;
26+
>foo : (arg: Arg) => void
27+
>arg : Arg
28+
29+
foo({ mode: "numeric", data: new Uint8Array([30]) }); // Should error
30+
>foo({ mode: "numeric", data: new Uint8Array([30]) }) : void
31+
>foo : (arg: Arg) => void
32+
>{ mode: "numeric", data: new Uint8Array([30]) } : { mode: "numeric"; data: Uint8Array; }
33+
>mode : "numeric"
34+
>"numeric" : "numeric"
35+
>data : Uint8Array
36+
>new Uint8Array([30]) : Uint8Array
37+
>Uint8Array : Uint8ArrayConstructor
38+
>[30] : number[]
39+
>30 : 30
40+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
type Arg = {
5+
mode: "numeric",
6+
data: number,
7+
} | {
8+
mode: "alphabetic",
9+
data: string,
10+
} | {
11+
data: string | Uint8Array;
12+
}
13+
14+
declare function foo(arg: Arg): void;
15+
foo({ mode: "numeric", data: new Uint8Array([30]) }); // Should error

0 commit comments

Comments
 (0)