mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-10 10:58:20 -05:00
Ensure empty array literal is assignable to never[] (#47816)
* Ensure empty array literal is assignable to never[] * Add tests * Add comment
This commit is contained in:
@@ -17907,8 +17907,10 @@ namespace ts {
|
||||
(source as LiteralType).value === (target as LiteralType).value &&
|
||||
isEnumTypeRelatedTo(getParentOfSymbol(source.symbol)!, getParentOfSymbol(target.symbol)!, errorReporter)) return true;
|
||||
}
|
||||
if (s & TypeFlags.Undefined && (!strictNullChecks || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
|
||||
if (s & TypeFlags.Null && (!strictNullChecks || t & TypeFlags.Null)) return true;
|
||||
// In non-strictNullChecks mode, `undefined` and `null` are assignable to anything except `never`.
|
||||
// Since unions and intersections may reduce to `never`, we exclude them here.
|
||||
if (s & TypeFlags.Undefined && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
|
||||
if (s & TypeFlags.Null && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & TypeFlags.Null)) return true;
|
||||
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true;
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (s & TypeFlags.Any) return true;
|
||||
@@ -19427,6 +19429,11 @@ namespace ts {
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target &&
|
||||
!isTupleType(source) && !(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) {
|
||||
// When strictNullChecks is disabled, the element type of the empty array literal is undefinedWideningType,
|
||||
// and an empty array literal wouldn't be assignable to a `never[]` without this check.
|
||||
if (isEmptyArrayLiteralType(source)) {
|
||||
return Ternary.True;
|
||||
}
|
||||
// We have type references to the same generic type, and the type references are not marker
|
||||
// type references (which are intended by be compared structurally). Obtain the variance
|
||||
// information for the type parameters and relate the type arguments accordingly.
|
||||
|
||||
@@ -63,4 +63,26 @@ tests/cases/conformance/types/never/neverTypeErrors1.ts(24,17): error TS2407: Th
|
||||
for (const n in f4()) {}
|
||||
~~~~
|
||||
!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'never'.
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,6 +23,28 @@ function f4(): never {
|
||||
|
||||
for (const n of f4()) {}
|
||||
for (const n in f4()) {}
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//// [neverTypeErrors1.js]
|
||||
@@ -48,3 +70,11 @@ for (var _i = 0, _a = f4(); _i < _a.length; _i++) {
|
||||
var n = _a[_i];
|
||||
}
|
||||
for (var n in f4()) { }
|
||||
function f5() {
|
||||
var x = []; // Ok
|
||||
}
|
||||
function func() {
|
||||
return {
|
||||
value: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,3 +52,43 @@ for (const n in f4()) {}
|
||||
>n : Symbol(n, Decl(neverTypeErrors1.ts, 23, 10))
|
||||
>f4 : Symbol(f4, Decl(neverTypeErrors1.ts, 17, 1))
|
||||
|
||||
function f5() {
|
||||
>f5 : Symbol(f5, Decl(neverTypeErrors1.ts, 23, 24))
|
||||
|
||||
let x: never[] = []; // Ok
|
||||
>x : Symbol(x, Decl(neverTypeErrors1.ts, 26, 7))
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(neverTypeErrors1.ts, 27, 1))
|
||||
|
||||
foo: "a";
|
||||
>foo : Symbol(A.foo, Decl(neverTypeErrors1.ts, 31, 13))
|
||||
}
|
||||
|
||||
interface B {
|
||||
>B : Symbol(B, Decl(neverTypeErrors1.ts, 33, 1))
|
||||
|
||||
foo: "b";
|
||||
>foo : Symbol(B.foo, Decl(neverTypeErrors1.ts, 35, 13))
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
>Union : Symbol(Union, Decl(neverTypeErrors1.ts, 37, 1))
|
||||
>A : Symbol(A, Decl(neverTypeErrors1.ts, 27, 1))
|
||||
>B : Symbol(B, Decl(neverTypeErrors1.ts, 33, 1))
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
>func : Symbol(func, Decl(neverTypeErrors1.ts, 39, 19))
|
||||
>value : Symbol(value, Decl(neverTypeErrors1.ts, 41, 18))
|
||||
>Union : Symbol(Union, Decl(neverTypeErrors1.ts, 37, 1))
|
||||
|
||||
return {
|
||||
value: [],
|
||||
>value : Symbol(value, Decl(neverTypeErrors1.ts, 42, 12))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -67,3 +67,40 @@ for (const n in f4()) {}
|
||||
>f4() : never
|
||||
>f4 : () => never
|
||||
|
||||
function f5() {
|
||||
>f5 : () => void
|
||||
|
||||
let x: never[] = []; // Ok
|
||||
>x : never[]
|
||||
>[] : undefined[]
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
>foo : "a"
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
>foo : "b"
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
>Union : never
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
>func : () => { value: Union[];}
|
||||
>value : never[]
|
||||
|
||||
return {
|
||||
>{ value: [], } : { value: undefined[]; }
|
||||
|
||||
value: [],
|
||||
>value : undefined[]
|
||||
>[] : undefined[]
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -63,4 +63,26 @@ tests/cases/conformance/types/never/neverTypeErrors2.ts(24,17): error TS2407: Th
|
||||
for (const n in f4()) {}
|
||||
~~~~
|
||||
!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'never'.
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,6 +23,28 @@ function f4(): never {
|
||||
|
||||
for (const n of f4()) {}
|
||||
for (const n in f4()) {}
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//// [neverTypeErrors2.js]
|
||||
@@ -48,3 +70,11 @@ for (var _i = 0, _a = f4(); _i < _a.length; _i++) {
|
||||
var n = _a[_i];
|
||||
}
|
||||
for (var n in f4()) { }
|
||||
function f5() {
|
||||
var x = []; // Ok
|
||||
}
|
||||
function func() {
|
||||
return {
|
||||
value: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,3 +52,43 @@ for (const n in f4()) {}
|
||||
>n : Symbol(n, Decl(neverTypeErrors2.ts, 23, 10))
|
||||
>f4 : Symbol(f4, Decl(neverTypeErrors2.ts, 17, 1))
|
||||
|
||||
function f5() {
|
||||
>f5 : Symbol(f5, Decl(neverTypeErrors2.ts, 23, 24))
|
||||
|
||||
let x: never[] = []; // Ok
|
||||
>x : Symbol(x, Decl(neverTypeErrors2.ts, 26, 7))
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(neverTypeErrors2.ts, 27, 1))
|
||||
|
||||
foo: "a";
|
||||
>foo : Symbol(A.foo, Decl(neverTypeErrors2.ts, 31, 13))
|
||||
}
|
||||
|
||||
interface B {
|
||||
>B : Symbol(B, Decl(neverTypeErrors2.ts, 33, 1))
|
||||
|
||||
foo: "b";
|
||||
>foo : Symbol(B.foo, Decl(neverTypeErrors2.ts, 35, 13))
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
>Union : Symbol(Union, Decl(neverTypeErrors2.ts, 37, 1))
|
||||
>A : Symbol(A, Decl(neverTypeErrors2.ts, 27, 1))
|
||||
>B : Symbol(B, Decl(neverTypeErrors2.ts, 33, 1))
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
>func : Symbol(func, Decl(neverTypeErrors2.ts, 39, 19))
|
||||
>value : Symbol(value, Decl(neverTypeErrors2.ts, 41, 18))
|
||||
>Union : Symbol(Union, Decl(neverTypeErrors2.ts, 37, 1))
|
||||
|
||||
return {
|
||||
value: [],
|
||||
>value : Symbol(value, Decl(neverTypeErrors2.ts, 42, 12))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -67,3 +67,40 @@ for (const n in f4()) {}
|
||||
>f4() : never
|
||||
>f4 : () => never
|
||||
|
||||
function f5() {
|
||||
>f5 : () => void
|
||||
|
||||
let x: never[] = []; // Ok
|
||||
>x : never[]
|
||||
>[] : never[]
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
>foo : "a"
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
>foo : "b"
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
>Union : never
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
>func : () => { value: Union[];}
|
||||
>value : never[]
|
||||
|
||||
return {
|
||||
>{ value: [], } : { value: never[]; }
|
||||
|
||||
value: [],
|
||||
>value : never[]
|
||||
>[] : never[]
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -22,3 +22,25 @@ function f4(): never {
|
||||
|
||||
for (const n of f4()) {}
|
||||
for (const n in f4()) {}
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,3 +24,25 @@ function f4(): never {
|
||||
|
||||
for (const n of f4()) {}
|
||||
for (const n in f4()) {}
|
||||
|
||||
function f5() {
|
||||
let x: never[] = []; // Ok
|
||||
}
|
||||
|
||||
// Repro from #46032
|
||||
|
||||
interface A {
|
||||
foo: "a";
|
||||
}
|
||||
|
||||
interface B {
|
||||
foo: "b";
|
||||
}
|
||||
|
||||
type Union = A & B;
|
||||
|
||||
function func(): { value: Union[] } {
|
||||
return {
|
||||
value: [],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user