mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Add Support for Using Aliased Discriminants in Conditional Statements (#56173)
This commit is contained in:
parent
50f48840a3
commit
7b96c28e8f
@ -27244,6 +27244,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
// The resolvedSymbol property is initialized by checkPropertyAccess or checkElementAccess before we get here.
|
||||
return isConstantReference((node as AccessExpression).expression) && isReadonlySymbol(getNodeLinks(node).resolvedSymbol || unknownSymbol);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
const rootDeclaration = getRootDeclaration(node.parent);
|
||||
return isVariableDeclaration(rootDeclaration) && isVarConstLike(rootDeclaration);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -0,0 +1,129 @@
|
||||
controlFlowAliasedDiscriminants.ts(39,9): error TS18048: 'data1' is possibly 'undefined'.
|
||||
controlFlowAliasedDiscriminants.ts(40,9): error TS18048: 'data2' is possibly 'undefined'.
|
||||
controlFlowAliasedDiscriminants.ts(65,9): error TS18048: 'bar2' is possibly 'undefined'.
|
||||
controlFlowAliasedDiscriminants.ts(66,9): error TS18048: 'bar3' is possibly 'undefined'.
|
||||
controlFlowAliasedDiscriminants.ts(86,14): error TS1360: Type 'string | number' does not satisfy the expected type 'string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
controlFlowAliasedDiscriminants.ts(98,19): error TS1360: Type 'string | number' does not satisfy the expected type 'string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== controlFlowAliasedDiscriminants.ts (6 errors) ====
|
||||
type UseQueryResult<T> = {
|
||||
isSuccess: false;
|
||||
data: undefined;
|
||||
} | {
|
||||
isSuccess: true;
|
||||
data: T
|
||||
};
|
||||
|
||||
function useQuery(): UseQueryResult<number> {
|
||||
return {
|
||||
isSuccess: false,
|
||||
data: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
const { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
{
|
||||
let { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
let { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should error
|
||||
~~~~~
|
||||
!!! error TS18048: 'data1' is possibly 'undefined'.
|
||||
data2.toExponential(); // should error
|
||||
~~~~~
|
||||
!!! error TS18048: 'data2' is possibly 'undefined'.
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
declare function getArrayResult(): [true, number] | [false, undefined];
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
const [foo2, bar2] = getArrayResult();
|
||||
const [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should ok
|
||||
bar3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
let [foo2, bar2] = getArrayResult();
|
||||
let [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should error
|
||||
~~~~
|
||||
!!! error TS18048: 'bar2' is possibly 'undefined'.
|
||||
bar3.toExponential(); // should error
|
||||
~~~~
|
||||
!!! error TS18048: 'bar3' is possibly 'undefined'.
|
||||
}
|
||||
}
|
||||
|
||||
type Nested = {
|
||||
type: 'string';
|
||||
resp: {
|
||||
data: string
|
||||
}
|
||||
} | {
|
||||
type: 'number';
|
||||
resp: {
|
||||
data: number;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let resp!: Nested;
|
||||
const { resp: { data }, type } = resp;
|
||||
if (type === 'string') {
|
||||
data satisfies string;
|
||||
~~~~~~~~~
|
||||
!!! error TS1360: Type 'string | number' does not satisfy the expected type 'string'.
|
||||
!!! error TS1360: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
let resp!: Nested;
|
||||
const { resp: { data: dataAlias }, type } = resp;
|
||||
if (type === 'string') {
|
||||
dataAlias satisfies string;
|
||||
~~~~~~~~~
|
||||
!!! error TS1360: Type 'string | number' does not satisfy the expected type 'string'.
|
||||
!!! error TS1360: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
|
||||
182
tests/baselines/reference/controlFlowAliasedDiscriminants.js
Normal file
182
tests/baselines/reference/controlFlowAliasedDiscriminants.js
Normal file
@ -0,0 +1,182 @@
|
||||
//// [tests/cases/compiler/controlFlowAliasedDiscriminants.ts] ////
|
||||
|
||||
//// [controlFlowAliasedDiscriminants.ts]
|
||||
type UseQueryResult<T> = {
|
||||
isSuccess: false;
|
||||
data: undefined;
|
||||
} | {
|
||||
isSuccess: true;
|
||||
data: T
|
||||
};
|
||||
|
||||
function useQuery(): UseQueryResult<number> {
|
||||
return {
|
||||
isSuccess: false,
|
||||
data: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
const { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
{
|
||||
let { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
let { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should error
|
||||
data2.toExponential(); // should error
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
declare function getArrayResult(): [true, number] | [false, undefined];
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
const [foo2, bar2] = getArrayResult();
|
||||
const [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should ok
|
||||
bar3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
let [foo2, bar2] = getArrayResult();
|
||||
let [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should error
|
||||
bar3.toExponential(); // should error
|
||||
}
|
||||
}
|
||||
|
||||
type Nested = {
|
||||
type: 'string';
|
||||
resp: {
|
||||
data: string
|
||||
}
|
||||
} | {
|
||||
type: 'number';
|
||||
resp: {
|
||||
data: number;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let resp!: Nested;
|
||||
const { resp: { data }, type } = resp;
|
||||
if (type === 'string') {
|
||||
data satisfies string;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
let resp!: Nested;
|
||||
const { resp: { data: dataAlias }, type } = resp;
|
||||
if (type === 'string') {
|
||||
dataAlias satisfies string;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [controlFlowAliasedDiscriminants.js]
|
||||
function useQuery() {
|
||||
return {
|
||||
isSuccess: false,
|
||||
data: undefined,
|
||||
};
|
||||
}
|
||||
var _a = useQuery(), data1 = _a.data, isSuccess1 = _a.isSuccess;
|
||||
var _b = useQuery(), data2 = _b.data, isSuccess2 = _b.isSuccess;
|
||||
var _c = useQuery(), data3 = _c.data, isSuccess3 = _c.isSuccess;
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
var areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
{
|
||||
var _d = useQuery(), data1_1 = _d.data, isSuccess1_1 = _d.isSuccess;
|
||||
var _e = useQuery(), data2_1 = _e.data, isSuccess2_1 = _e.isSuccess;
|
||||
var _f = useQuery(), data3_1 = _f.data, isSuccess3_1 = _f.isSuccess;
|
||||
var areSuccess_1 = isSuccess1_1 && isSuccess2_1 && isSuccess3_1;
|
||||
if (areSuccess_1) {
|
||||
data1_1.toExponential(); // should error
|
||||
data2_1.toExponential(); // should error
|
||||
data3_1.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
{
|
||||
var _g = getArrayResult(), foo1 = _g[0], bar1 = _g[1];
|
||||
var _h = getArrayResult(), foo2 = _h[0], bar2 = _h[1];
|
||||
var _j = getArrayResult(), foo3 = _j[0], bar3 = _j[1];
|
||||
var arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should ok
|
||||
bar3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
{
|
||||
var _k = getArrayResult(), foo1 = _k[0], bar1 = _k[1];
|
||||
var _l = getArrayResult(), foo2 = _l[0], bar2 = _l[1];
|
||||
var _m = getArrayResult(), foo3 = _m[0], bar3 = _m[1];
|
||||
var arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should error
|
||||
bar3.toExponential(); // should error
|
||||
}
|
||||
}
|
||||
{
|
||||
var resp = void 0;
|
||||
var data = resp.resp.data, type = resp.type;
|
||||
if (type === 'string') {
|
||||
data;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data;
|
||||
}
|
||||
}
|
||||
{
|
||||
var resp = void 0;
|
||||
var dataAlias = resp.resp.data, type = resp.type;
|
||||
if (type === 'string') {
|
||||
dataAlias;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,327 @@
|
||||
//// [tests/cases/compiler/controlFlowAliasedDiscriminants.ts] ////
|
||||
|
||||
=== controlFlowAliasedDiscriminants.ts ===
|
||||
type UseQueryResult<T> = {
|
||||
>UseQueryResult : Symbol(UseQueryResult, Decl(controlFlowAliasedDiscriminants.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(controlFlowAliasedDiscriminants.ts, 0, 20))
|
||||
|
||||
isSuccess: false;
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26))
|
||||
|
||||
data: undefined;
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21))
|
||||
|
||||
} | {
|
||||
isSuccess: true;
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
|
||||
data: T
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>T : Symbol(T, Decl(controlFlowAliasedDiscriminants.ts, 0, 20))
|
||||
|
||||
};
|
||||
|
||||
function useQuery(): UseQueryResult<number> {
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
>UseQueryResult : Symbol(UseQueryResult, Decl(controlFlowAliasedDiscriminants.ts, 0, 0))
|
||||
|
||||
return {
|
||||
isSuccess: false,
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 9, 12))
|
||||
|
||||
data: undefined,
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 10, 25))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
const { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data1 : Symbol(data1, Decl(controlFlowAliasedDiscriminants.ts, 15, 7))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess1 : Symbol(isSuccess1, Decl(controlFlowAliasedDiscriminants.ts, 15, 20))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
const { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data2 : Symbol(data2, Decl(controlFlowAliasedDiscriminants.ts, 16, 7))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess2 : Symbol(isSuccess2, Decl(controlFlowAliasedDiscriminants.ts, 16, 20))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data3 : Symbol(data3, Decl(controlFlowAliasedDiscriminants.ts, 17, 7))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess3 : Symbol(isSuccess3, Decl(controlFlowAliasedDiscriminants.ts, 17, 20))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
>isSuccess1 : Symbol(isSuccess1, Decl(controlFlowAliasedDiscriminants.ts, 15, 20))
|
||||
>isSuccess2 : Symbol(isSuccess2, Decl(controlFlowAliasedDiscriminants.ts, 16, 20))
|
||||
>isSuccess3 : Symbol(isSuccess3, Decl(controlFlowAliasedDiscriminants.ts, 17, 20))
|
||||
|
||||
data1.toExponential(); // should ok
|
||||
>data1.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data1 : Symbol(data1, Decl(controlFlowAliasedDiscriminants.ts, 15, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data2.toExponential(); // should ok
|
||||
>data2.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data2 : Symbol(data2, Decl(controlFlowAliasedDiscriminants.ts, 16, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data3 : Symbol(data3, Decl(controlFlowAliasedDiscriminants.ts, 17, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
>areSuccess : Symbol(areSuccess, Decl(controlFlowAliasedDiscriminants.ts, 25, 5))
|
||||
>isSuccess1 : Symbol(isSuccess1, Decl(controlFlowAliasedDiscriminants.ts, 15, 20))
|
||||
>isSuccess2 : Symbol(isSuccess2, Decl(controlFlowAliasedDiscriminants.ts, 16, 20))
|
||||
>isSuccess3 : Symbol(isSuccess3, Decl(controlFlowAliasedDiscriminants.ts, 17, 20))
|
||||
|
||||
if (areSuccess) {
|
||||
>areSuccess : Symbol(areSuccess, Decl(controlFlowAliasedDiscriminants.ts, 25, 5))
|
||||
|
||||
data1.toExponential(); // should ok
|
||||
>data1.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data1 : Symbol(data1, Decl(controlFlowAliasedDiscriminants.ts, 15, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data2.toExponential(); // should ok
|
||||
>data2.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data2 : Symbol(data2, Decl(controlFlowAliasedDiscriminants.ts, 16, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data3 : Symbol(data3, Decl(controlFlowAliasedDiscriminants.ts, 17, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
{
|
||||
let { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data1 : Symbol(data1, Decl(controlFlowAliasedDiscriminants.ts, 33, 9))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess1 : Symbol(isSuccess1, Decl(controlFlowAliasedDiscriminants.ts, 33, 22))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
let { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data2 : Symbol(data2, Decl(controlFlowAliasedDiscriminants.ts, 34, 9))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess2 : Symbol(isSuccess2, Decl(controlFlowAliasedDiscriminants.ts, 34, 22))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 1, 21), Decl(controlFlowAliasedDiscriminants.ts, 4, 20))
|
||||
>data3 : Symbol(data3, Decl(controlFlowAliasedDiscriminants.ts, 35, 11))
|
||||
>isSuccess : Symbol(isSuccess, Decl(controlFlowAliasedDiscriminants.ts, 0, 26), Decl(controlFlowAliasedDiscriminants.ts, 3, 5))
|
||||
>isSuccess3 : Symbol(isSuccess3, Decl(controlFlowAliasedDiscriminants.ts, 35, 24))
|
||||
>useQuery : Symbol(useQuery, Decl(controlFlowAliasedDiscriminants.ts, 6, 2))
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
>areSuccess : Symbol(areSuccess, Decl(controlFlowAliasedDiscriminants.ts, 36, 9))
|
||||
>isSuccess1 : Symbol(isSuccess1, Decl(controlFlowAliasedDiscriminants.ts, 33, 22))
|
||||
>isSuccess2 : Symbol(isSuccess2, Decl(controlFlowAliasedDiscriminants.ts, 34, 22))
|
||||
>isSuccess3 : Symbol(isSuccess3, Decl(controlFlowAliasedDiscriminants.ts, 35, 24))
|
||||
|
||||
if (areSuccess) {
|
||||
>areSuccess : Symbol(areSuccess, Decl(controlFlowAliasedDiscriminants.ts, 36, 9))
|
||||
|
||||
data1.toExponential(); // should error
|
||||
>data1.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data1 : Symbol(data1, Decl(controlFlowAliasedDiscriminants.ts, 33, 9))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data2.toExponential(); // should error
|
||||
>data2.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data2 : Symbol(data2, Decl(controlFlowAliasedDiscriminants.ts, 34, 9))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>data3 : Symbol(data3, Decl(controlFlowAliasedDiscriminants.ts, 35, 11))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
declare function getArrayResult(): [true, number] | [false, undefined];
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
>foo1 : Symbol(foo1, Decl(controlFlowAliasedDiscriminants.ts, 46, 11))
|
||||
>bar1 : Symbol(bar1, Decl(controlFlowAliasedDiscriminants.ts, 46, 16))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
const [foo2, bar2] = getArrayResult();
|
||||
>foo2 : Symbol(foo2, Decl(controlFlowAliasedDiscriminants.ts, 47, 11))
|
||||
>bar2 : Symbol(bar2, Decl(controlFlowAliasedDiscriminants.ts, 47, 16))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
const [foo3, bar3] = getArrayResult();
|
||||
>foo3 : Symbol(foo3, Decl(controlFlowAliasedDiscriminants.ts, 48, 11))
|
||||
>bar3 : Symbol(bar3, Decl(controlFlowAliasedDiscriminants.ts, 48, 16))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
>arrayAllSuccess : Symbol(arrayAllSuccess, Decl(controlFlowAliasedDiscriminants.ts, 49, 9))
|
||||
>foo1 : Symbol(foo1, Decl(controlFlowAliasedDiscriminants.ts, 46, 11))
|
||||
>foo2 : Symbol(foo2, Decl(controlFlowAliasedDiscriminants.ts, 47, 11))
|
||||
>foo3 : Symbol(foo3, Decl(controlFlowAliasedDiscriminants.ts, 48, 11))
|
||||
|
||||
if (arrayAllSuccess) {
|
||||
>arrayAllSuccess : Symbol(arrayAllSuccess, Decl(controlFlowAliasedDiscriminants.ts, 49, 9))
|
||||
|
||||
bar1.toExponential(); // should ok
|
||||
>bar1.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar1 : Symbol(bar1, Decl(controlFlowAliasedDiscriminants.ts, 46, 16))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
bar2.toExponential(); // should ok
|
||||
>bar2.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar2 : Symbol(bar2, Decl(controlFlowAliasedDiscriminants.ts, 47, 16))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
bar3.toExponential(); // should ok
|
||||
>bar3.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar3 : Symbol(bar3, Decl(controlFlowAliasedDiscriminants.ts, 48, 16))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
>foo1 : Symbol(foo1, Decl(controlFlowAliasedDiscriminants.ts, 58, 11))
|
||||
>bar1 : Symbol(bar1, Decl(controlFlowAliasedDiscriminants.ts, 58, 16))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
let [foo2, bar2] = getArrayResult();
|
||||
>foo2 : Symbol(foo2, Decl(controlFlowAliasedDiscriminants.ts, 59, 9))
|
||||
>bar2 : Symbol(bar2, Decl(controlFlowAliasedDiscriminants.ts, 59, 14))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
let [foo3, bar3] = getArrayResult();
|
||||
>foo3 : Symbol(foo3, Decl(controlFlowAliasedDiscriminants.ts, 60, 9))
|
||||
>bar3 : Symbol(bar3, Decl(controlFlowAliasedDiscriminants.ts, 60, 14))
|
||||
>getArrayResult : Symbol(getArrayResult, Decl(controlFlowAliasedDiscriminants.ts, 42, 1))
|
||||
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
>arrayAllSuccess : Symbol(arrayAllSuccess, Decl(controlFlowAliasedDiscriminants.ts, 61, 9))
|
||||
>foo1 : Symbol(foo1, Decl(controlFlowAliasedDiscriminants.ts, 58, 11))
|
||||
>foo2 : Symbol(foo2, Decl(controlFlowAliasedDiscriminants.ts, 59, 9))
|
||||
>foo3 : Symbol(foo3, Decl(controlFlowAliasedDiscriminants.ts, 60, 9))
|
||||
|
||||
if (arrayAllSuccess) {
|
||||
>arrayAllSuccess : Symbol(arrayAllSuccess, Decl(controlFlowAliasedDiscriminants.ts, 61, 9))
|
||||
|
||||
bar1.toExponential(); // should ok
|
||||
>bar1.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar1 : Symbol(bar1, Decl(controlFlowAliasedDiscriminants.ts, 58, 16))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
bar2.toExponential(); // should error
|
||||
>bar2.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar2 : Symbol(bar2, Decl(controlFlowAliasedDiscriminants.ts, 59, 14))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
bar3.toExponential(); // should error
|
||||
>bar3.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>bar3 : Symbol(bar3, Decl(controlFlowAliasedDiscriminants.ts, 60, 14))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
type Nested = {
|
||||
>Nested : Symbol(Nested, Decl(controlFlowAliasedDiscriminants.ts, 67, 1))
|
||||
|
||||
type: 'string';
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 69, 15))
|
||||
|
||||
resp: {
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19))
|
||||
|
||||
data: string
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11))
|
||||
}
|
||||
} | {
|
||||
type: 'number';
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 74, 5))
|
||||
|
||||
resp: {
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 75, 19))
|
||||
|
||||
data: number;
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 76, 11))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let resp!: Nested;
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 82, 7))
|
||||
>Nested : Symbol(Nested, Decl(controlFlowAliasedDiscriminants.ts, 67, 1))
|
||||
|
||||
const { resp: { data }, type } = resp;
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19), Decl(controlFlowAliasedDiscriminants.ts, 75, 19))
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 83, 19))
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 83, 27))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 82, 7))
|
||||
|
||||
if (type === 'string') {
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 83, 27))
|
||||
|
||||
data satisfies string;
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 83, 19))
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
>resp.type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 69, 15), Decl(controlFlowAliasedDiscriminants.ts, 74, 5))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 82, 7))
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 69, 15), Decl(controlFlowAliasedDiscriminants.ts, 74, 5))
|
||||
|
||||
resp.resp.data satisfies string;
|
||||
>resp.resp.data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11))
|
||||
>resp.resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 82, 7))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19))
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
let resp!: Nested;
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 94, 7))
|
||||
>Nested : Symbol(Nested, Decl(controlFlowAliasedDiscriminants.ts, 67, 1))
|
||||
|
||||
const { resp: { data: dataAlias }, type } = resp;
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19), Decl(controlFlowAliasedDiscriminants.ts, 75, 19))
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11), Decl(controlFlowAliasedDiscriminants.ts, 76, 11))
|
||||
>dataAlias : Symbol(dataAlias, Decl(controlFlowAliasedDiscriminants.ts, 95, 19))
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 95, 38))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 94, 7))
|
||||
|
||||
if (type === 'string') {
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 95, 38))
|
||||
|
||||
dataAlias satisfies string;
|
||||
>dataAlias : Symbol(dataAlias, Decl(controlFlowAliasedDiscriminants.ts, 95, 19))
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
>resp.type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 69, 15), Decl(controlFlowAliasedDiscriminants.ts, 74, 5))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 94, 7))
|
||||
>type : Symbol(type, Decl(controlFlowAliasedDiscriminants.ts, 69, 15), Decl(controlFlowAliasedDiscriminants.ts, 74, 5))
|
||||
|
||||
resp.resp.data satisfies string;
|
||||
>resp.resp.data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11))
|
||||
>resp.resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 94, 7))
|
||||
>resp : Symbol(resp, Decl(controlFlowAliasedDiscriminants.ts, 70, 19))
|
||||
>data : Symbol(data, Decl(controlFlowAliasedDiscriminants.ts, 71, 11))
|
||||
}
|
||||
}
|
||||
|
||||
378
tests/baselines/reference/controlFlowAliasedDiscriminants.types
Normal file
378
tests/baselines/reference/controlFlowAliasedDiscriminants.types
Normal file
@ -0,0 +1,378 @@
|
||||
//// [tests/cases/compiler/controlFlowAliasedDiscriminants.ts] ////
|
||||
|
||||
=== controlFlowAliasedDiscriminants.ts ===
|
||||
type UseQueryResult<T> = {
|
||||
>UseQueryResult : UseQueryResult<T>
|
||||
|
||||
isSuccess: false;
|
||||
>isSuccess : false
|
||||
>false : false
|
||||
|
||||
data: undefined;
|
||||
>data : undefined
|
||||
|
||||
} | {
|
||||
isSuccess: true;
|
||||
>isSuccess : true
|
||||
>true : true
|
||||
|
||||
data: T
|
||||
>data : T
|
||||
|
||||
};
|
||||
|
||||
function useQuery(): UseQueryResult<number> {
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
return {
|
||||
>{ isSuccess: false, data: undefined, } : { isSuccess: false; data: undefined; }
|
||||
|
||||
isSuccess: false,
|
||||
>isSuccess : false
|
||||
>false : false
|
||||
|
||||
data: undefined,
|
||||
>data : undefined
|
||||
>undefined : undefined
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
const { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
>data : any
|
||||
>data1 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess1 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
const { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
>data : any
|
||||
>data2 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess2 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
>data : any
|
||||
>data3 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess3 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
>isSuccess1 && isSuccess2 && isSuccess3 : boolean
|
||||
>isSuccess1 && isSuccess2 : boolean
|
||||
>isSuccess1 : boolean
|
||||
>isSuccess2 : boolean
|
||||
>isSuccess3 : boolean
|
||||
|
||||
data1.toExponential(); // should ok
|
||||
>data1.toExponential() : string
|
||||
>data1.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data1 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data2.toExponential(); // should ok
|
||||
>data2.toExponential() : string
|
||||
>data2.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data2 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential() : string
|
||||
>data3.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data3 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
>areSuccess : boolean
|
||||
>isSuccess1 && isSuccess2 && isSuccess3 : boolean
|
||||
>isSuccess1 && isSuccess2 : boolean
|
||||
>isSuccess1 : boolean
|
||||
>isSuccess2 : boolean
|
||||
>isSuccess3 : boolean
|
||||
|
||||
if (areSuccess) {
|
||||
>areSuccess : boolean
|
||||
|
||||
data1.toExponential(); // should ok
|
||||
>data1.toExponential() : string
|
||||
>data1.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data1 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data2.toExponential(); // should ok
|
||||
>data2.toExponential() : string
|
||||
>data2.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data2 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential() : string
|
||||
>data3.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data3 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
|
||||
{
|
||||
let { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
>data : any
|
||||
>data1 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess1 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
let { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
>data : any
|
||||
>data2 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess2 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
>data : any
|
||||
>data3 : number | undefined
|
||||
>isSuccess : any
|
||||
>isSuccess3 : boolean
|
||||
>useQuery() : UseQueryResult<number>
|
||||
>useQuery : () => UseQueryResult<number>
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
>areSuccess : boolean
|
||||
>isSuccess1 && isSuccess2 && isSuccess3 : boolean
|
||||
>isSuccess1 && isSuccess2 : boolean
|
||||
>isSuccess1 : boolean
|
||||
>isSuccess2 : boolean
|
||||
>isSuccess3 : boolean
|
||||
|
||||
if (areSuccess) {
|
||||
>areSuccess : boolean
|
||||
|
||||
data1.toExponential(); // should error
|
||||
>data1.toExponential() : string
|
||||
>data1.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data1 : number | undefined
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data2.toExponential(); // should error
|
||||
>data2.toExponential() : string
|
||||
>data2.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data2 : number | undefined
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
data3.toExponential(); // should ok
|
||||
>data3.toExponential() : string
|
||||
>data3.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>data3 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
}
|
||||
|
||||
declare function getArrayResult(): [true, number] | [false, undefined];
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
>true : true
|
||||
>false : false
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
>foo1 : boolean
|
||||
>bar1 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
const [foo2, bar2] = getArrayResult();
|
||||
>foo2 : boolean
|
||||
>bar2 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
const [foo3, bar3] = getArrayResult();
|
||||
>foo3 : boolean
|
||||
>bar3 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
>arrayAllSuccess : boolean
|
||||
>foo1 && foo2 && foo3 : boolean
|
||||
>foo1 && foo2 : boolean
|
||||
>foo1 : boolean
|
||||
>foo2 : boolean
|
||||
>foo3 : boolean
|
||||
|
||||
if (arrayAllSuccess) {
|
||||
>arrayAllSuccess : boolean
|
||||
|
||||
bar1.toExponential(); // should ok
|
||||
>bar1.toExponential() : string
|
||||
>bar1.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar1 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
bar2.toExponential(); // should ok
|
||||
>bar2.toExponential() : string
|
||||
>bar2.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar2 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
bar3.toExponential(); // should ok
|
||||
>bar3.toExponential() : string
|
||||
>bar3.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar3 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
>foo1 : boolean
|
||||
>bar1 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
let [foo2, bar2] = getArrayResult();
|
||||
>foo2 : boolean
|
||||
>bar2 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
let [foo3, bar3] = getArrayResult();
|
||||
>foo3 : boolean
|
||||
>bar3 : number | undefined
|
||||
>getArrayResult() : [true, number] | [false, undefined]
|
||||
>getArrayResult : () => [true, number] | [false, undefined]
|
||||
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
>arrayAllSuccess : boolean
|
||||
>foo1 && foo2 && foo3 : boolean
|
||||
>foo1 && foo2 : boolean
|
||||
>foo1 : boolean
|
||||
>foo2 : boolean
|
||||
>foo3 : boolean
|
||||
|
||||
if (arrayAllSuccess) {
|
||||
>arrayAllSuccess : boolean
|
||||
|
||||
bar1.toExponential(); // should ok
|
||||
>bar1.toExponential() : string
|
||||
>bar1.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar1 : number
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
bar2.toExponential(); // should error
|
||||
>bar2.toExponential() : string
|
||||
>bar2.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar2 : number | undefined
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
|
||||
bar3.toExponential(); // should error
|
||||
>bar3.toExponential() : string
|
||||
>bar3.toExponential : (fractionDigits?: number | undefined) => string
|
||||
>bar3 : number | undefined
|
||||
>toExponential : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
}
|
||||
|
||||
type Nested = {
|
||||
>Nested : { type: 'string'; resp: { data: string;}; } | { type: 'number'; resp: { data: number;}; }
|
||||
|
||||
type: 'string';
|
||||
>type : "string"
|
||||
|
||||
resp: {
|
||||
>resp : { data: string; }
|
||||
|
||||
data: string
|
||||
>data : string
|
||||
}
|
||||
} | {
|
||||
type: 'number';
|
||||
>type : "number"
|
||||
|
||||
resp: {
|
||||
>resp : { data: number; }
|
||||
|
||||
data: number;
|
||||
>data : number
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let resp!: Nested;
|
||||
>resp : Nested
|
||||
|
||||
const { resp: { data }, type } = resp;
|
||||
>resp : any
|
||||
>data : string | number
|
||||
>type : "string" | "number"
|
||||
>resp : Nested
|
||||
|
||||
if (type === 'string') {
|
||||
>type === 'string' : boolean
|
||||
>type : "string" | "number"
|
||||
>'string' : "string"
|
||||
|
||||
data satisfies string;
|
||||
>data satisfies string : string | number
|
||||
>data : string | number
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
>resp.type === 'string' : boolean
|
||||
>resp.type : "string" | "number"
|
||||
>resp : Nested
|
||||
>type : "string" | "number"
|
||||
>'string' : "string"
|
||||
|
||||
resp.resp.data satisfies string;
|
||||
>resp.resp.data satisfies string : string
|
||||
>resp.resp.data : string
|
||||
>resp.resp : { data: string; }
|
||||
>resp : { type: "string"; resp: { data: string; }; }
|
||||
>resp : { data: string; }
|
||||
>data : string
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
let resp!: Nested;
|
||||
>resp : Nested
|
||||
|
||||
const { resp: { data: dataAlias }, type } = resp;
|
||||
>resp : any
|
||||
>data : any
|
||||
>dataAlias : string | number
|
||||
>type : "string" | "number"
|
||||
>resp : Nested
|
||||
|
||||
if (type === 'string') {
|
||||
>type === 'string' : boolean
|
||||
>type : "string" | "number"
|
||||
>'string' : "string"
|
||||
|
||||
dataAlias satisfies string;
|
||||
>dataAlias satisfies string : string | number
|
||||
>dataAlias : string | number
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
>resp.type === 'string' : boolean
|
||||
>resp.type : "string" | "number"
|
||||
>resp : Nested
|
||||
>type : "string" | "number"
|
||||
>'string' : "string"
|
||||
|
||||
resp.resp.data satisfies string;
|
||||
>resp.resp.data satisfies string : string
|
||||
>resp.resp.data : string
|
||||
>resp.resp : { data: string; }
|
||||
>resp : { type: "string"; resp: { data: string; }; }
|
||||
>resp : { data: string; }
|
||||
>data : string
|
||||
}
|
||||
}
|
||||
|
||||
106
tests/cases/compiler/controlFlowAliasedDiscriminants.ts
Normal file
106
tests/cases/compiler/controlFlowAliasedDiscriminants.ts
Normal file
@ -0,0 +1,106 @@
|
||||
// @strictNullChecks: true
|
||||
// @noImplicitAny: true
|
||||
|
||||
type UseQueryResult<T> = {
|
||||
isSuccess: false;
|
||||
data: undefined;
|
||||
} | {
|
||||
isSuccess: true;
|
||||
data: T
|
||||
};
|
||||
|
||||
function useQuery(): UseQueryResult<number> {
|
||||
return {
|
||||
isSuccess: false,
|
||||
data: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
const { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
|
||||
if (isSuccess1 && isSuccess2 && isSuccess3) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should ok
|
||||
data2.toExponential(); // should ok
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
|
||||
{
|
||||
let { data: data1, isSuccess: isSuccess1 } = useQuery();
|
||||
let { data: data2, isSuccess: isSuccess2 } = useQuery();
|
||||
const { data: data3, isSuccess: isSuccess3 } = useQuery();
|
||||
const areSuccess = isSuccess1 && isSuccess2 && isSuccess3;
|
||||
if (areSuccess) {
|
||||
data1.toExponential(); // should error
|
||||
data2.toExponential(); // should error
|
||||
data3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
declare function getArrayResult(): [true, number] | [false, undefined];
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
const [foo2, bar2] = getArrayResult();
|
||||
const [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should ok
|
||||
bar3.toExponential(); // should ok
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const [foo1, bar1] = getArrayResult();
|
||||
let [foo2, bar2] = getArrayResult();
|
||||
let [foo3, bar3] = getArrayResult();
|
||||
const arrayAllSuccess = foo1 && foo2 && foo3;
|
||||
if (arrayAllSuccess) {
|
||||
bar1.toExponential(); // should ok
|
||||
bar2.toExponential(); // should error
|
||||
bar3.toExponential(); // should error
|
||||
}
|
||||
}
|
||||
|
||||
type Nested = {
|
||||
type: 'string';
|
||||
resp: {
|
||||
data: string
|
||||
}
|
||||
} | {
|
||||
type: 'number';
|
||||
resp: {
|
||||
data: number;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let resp!: Nested;
|
||||
const { resp: { data }, type } = resp;
|
||||
if (type === 'string') {
|
||||
data satisfies string;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
let resp!: Nested;
|
||||
const { resp: { data: dataAlias }, type } = resp;
|
||||
if (type === 'string') {
|
||||
dataAlias satisfies string;
|
||||
}
|
||||
if (resp.type === 'string') {
|
||||
resp.resp.data satisfies string;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user