• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) Microsoft Corporation. All rights reserved.
3* Copyright (c) 2023 Huawei Device Co., Ltd.
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8*     http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*
16* This file has been modified by Huawei to verify type inference by adding verification statements.
17*/
18
19// === tests/cases/compiler/narrowingAssignmentReadonlyRespectsAssertion.ts ===
20declare function AssertType(value:any, type:string):void;
21// https://github.com/microsoft/TypeScript/issues/41984
22
23interface TestCase<T extends string | number> {
24  readonly val1: T | ReadonlyArray<T>;
25  readonly val2: ReadonlyArray<T>;
26}
27
28interface MultiCaseFixture<T> {
29  cases: T[];
30}
31
32function subDataFunc(): TestCase<string | number>[] {
33AssertType([      { val1: "a", val2: ["a", "b", "c"] },      { val1: 2, val2: [1, 2, 3] },      { val1: ["a", "z"], val2: ["x", "y", "z"] },      { val1: [5, 10], val2: [10, 100, 1000] },  ], "(union)[]");
34  return [
35
36      { val1: "a", val2: ["a", "b", "c"] },
37AssertType({ val1: "a", val2: ["a", "b", "c"] }, "{ val1: string; val2: string[]; }");
38AssertType(val1, "string");
39AssertType("a", "string");
40AssertType(val2, "string[]");
41AssertType(["a", "b", "c"], "string[]");
42AssertType("a", "string");
43AssertType("b", "string");
44AssertType("c", "string");
45
46      { val1: 2, val2: [1, 2, 3] },
47AssertType({ val1: 2, val2: [1, 2, 3] }, "{ val1: number; val2: number[]; }");
48AssertType(val1, "number");
49AssertType(2, "int");
50AssertType(val2, "number[]");
51AssertType([1, 2, 3], "number[]");
52AssertType(1, "int");
53AssertType(2, "int");
54AssertType(3, "int");
55
56      { val1: ["a", "z"], val2: ["x", "y", "z"] },
57AssertType({ val1: ["a", "z"], val2: ["x", "y", "z"] }, "{ val1: string[]; val2: string[]; }");
58AssertType(val1, "string[]");
59AssertType(["a", "z"], "string[]");
60AssertType("a", "string");
61AssertType("z", "string");
62AssertType(val2, "string[]");
63AssertType(["x", "y", "z"], "string[]");
64AssertType("x", "string");
65AssertType("y", "string");
66AssertType("z", "string");
67
68      { val1: [5, 10], val2: [10, 100, 1000] },
69AssertType({ val1: [5, 10], val2: [10, 100, 1000] }, "{ val1: number[]; val2: number[]; }");
70AssertType(val1, "number[]");
71AssertType([5, 10], "number[]");
72AssertType(5, "int");
73AssertType(10, "int");
74AssertType(val2, "number[]");
75AssertType([10, 100, 1000], "number[]");
76AssertType(10, "int");
77AssertType(100, "int");
78AssertType(1000, "int");
79
80  ];
81}
82
83function dataFunc<T>(subFunc: () => T[]): MultiCaseFixture<T> {
84AssertType({ cases: subFunc() }, "{ cases: T[]; }");
85AssertType(cases, "T[]");
86AssertType(subFunc(), "T[]");
87AssertType(subFunc, "() => T[]");
88  return { cases: subFunc() };
89}
90
91function testFunc() {
92  const fixture = dataFunc<TestCase<string | number>>(subDataFunc);
93AssertType(fixture, "MultiCaseFixture<TestCase<union>>");
94AssertType(dataFunc<TestCase<string | number>>(subDataFunc), "MultiCaseFixture<TestCase<union>>");
95AssertType(dataFunc, "<T>(() => T[]) => MultiCaseFixture<T>");
96AssertType(subDataFunc, "() => TestCase<union>[]");
97
98  fixture.cases.forEach(({ val1, val2 }) => {
99AssertType(fixture.cases.forEach(({ val1, val2 }) => {      if (Array.isArray(val1)) {          // This should retain val1 as being an array          const reversedVal1 = val1.slice().reverse();          console.log(reversedVal1);      } else {          console.log(val1);      }      console.log(val2);  }), "void");
100AssertType(fixture.cases.forEach, "((TestCase<union>, number, TestCase<union>[]) => void, ?any) => void");
101AssertType(fixture.cases, "TestCase<union>[]");
102AssertType(({ val1, val2 }) => {      if (Array.isArray(val1)) {          // This should retain val1 as being an array          const reversedVal1 = val1.slice().reverse();          console.log(reversedVal1);      } else {          console.log(val1);      }      console.log(val2);  }, "(TestCase<union>) => void");
103AssertType(val1, "union");
104AssertType(val2, "readonly (union)[]");
105
106      if (Array.isArray(val1)) {
107AssertType(Array.isArray(val1), "boolean");
108AssertType(Array.isArray, "(any) => arg is any[]");
109AssertType(val1, "union");
110
111          // This should retain val1 as being an array
112          const reversedVal1 = val1.slice().reverse();
113AssertType(reversedVal1, "any[]");
114AssertType(val1.slice().reverse(), "any[]");
115AssertType(val1.slice().reverse, "() => any[]");
116AssertType(val1.slice(), "any[]");
117AssertType(val1.slice, "(?number, ?number) => any[]");
118
119          console.log(reversedVal1);
120AssertType(console.log(reversedVal1), "void");
121AssertType(console.log, "(...any[]) => void");
122AssertType(reversedVal1, "any[]");
123
124      } else {
125          console.log(val1);
126AssertType(console.log(val1), "void");
127AssertType(console.log, "(...any[]) => void");
128AssertType(val1, "union");
129      }
130      console.log(val2);
131AssertType(console.log(val2), "void");
132AssertType(console.log, "(...any[]) => void");
133AssertType(val2, "readonly (union)[]");
134
135  });
136}
137
138testFunc();
139AssertType(testFunc(), "void");
140AssertType(testFunc, "() => void");
141
142
143