mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Treat void-typed properties as optional
This commit is contained in:
+24
-4
@@ -1352,6 +1352,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return the `SymbolLinks` for `symbol`, if one already exists.
|
||||
* Does not allocate a symbol id or a `SymbolLinks` if it doesn't already exists.
|
||||
*/
|
||||
function tryGetSymbolLinks(symbol: Symbol): SymbolLinks | undefined {
|
||||
if (symbol.flags & SymbolFlags.Transient) return <TransientSymbol>symbol;
|
||||
return symbol.id ? symbolLinks[symbol.id] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a `SymbolLinks` for `symbol`.
|
||||
*/
|
||||
function getSymbolLinks(symbol: Symbol): SymbolLinks {
|
||||
if (symbol.flags & SymbolFlags.Transient) return <TransientSymbol>symbol;
|
||||
const id = getSymbolId(symbol);
|
||||
@@ -7666,11 +7678,11 @@ namespace ts {
|
||||
function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
|
||||
switch (propertyName) {
|
||||
case TypeSystemPropertyName.Type:
|
||||
return !!getSymbolLinks(<Symbol>target).type;
|
||||
return !!tryGetSymbolLinks(<Symbol>target)?.type;
|
||||
case TypeSystemPropertyName.EnumTagType:
|
||||
return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
|
||||
case TypeSystemPropertyName.DeclaredType:
|
||||
return !!getSymbolLinks(<Symbol>target).declaredType;
|
||||
return !!tryGetSymbolLinks(<Symbol>target)?.declaredType;
|
||||
case TypeSystemPropertyName.ResolvedBaseConstructorType:
|
||||
return !!(<InterfaceType>target).resolvedBaseConstructorType;
|
||||
case TypeSystemPropertyName.ResolvedReturnType:
|
||||
@@ -8509,6 +8521,14 @@ namespace ts {
|
||||
return links.type;
|
||||
}
|
||||
|
||||
function isOptionalProperty(prop: Symbol) {
|
||||
if (prop.flags & SymbolFlags.Optional) return true;
|
||||
// We don't use `getTypeOfSymbol` here as we may be in the middle of resolving the type for `prop` and
|
||||
// we shouldn't re-enter to check for `void`.
|
||||
const type = tryGetSymbolLinks(prop)?.type;
|
||||
return !!(type && forEachType(type, acceptsVoid));
|
||||
}
|
||||
|
||||
function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol) {
|
||||
// Handle prototype property
|
||||
if (symbol.flags & SymbolFlags.Prototype) {
|
||||
@@ -17894,7 +17914,7 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
// When checking for comparability, be more lenient with optional properties.
|
||||
if (!skipOptional && sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) {
|
||||
if (!skipOptional && sourceProp.flags & SymbolFlags.Optional && !isOptionalProperty(targetProp)) {
|
||||
// TypeScript 1.0 spec (April 2014): 3.8.3
|
||||
// S is a subtype of a type T, and T is a supertype of S if ...
|
||||
// S' and T are object types and, for each member M in T..
|
||||
@@ -19709,7 +19729,7 @@ namespace ts {
|
||||
if (isStaticPrivateIdentifierProperty(targetProp)) {
|
||||
continue;
|
||||
}
|
||||
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional || getCheckFlags(targetProp) & CheckFlags.Partial)) {
|
||||
if (requireOptionalProperties || !((getCheckFlags(targetProp) & CheckFlags.Partial) || isOptionalProperty(targetProp))) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (!sourceProp) {
|
||||
yield targetProp;
|
||||
|
||||
@@ -22,7 +22,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import(
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -42,7 +42,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import(
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -66,7 +66,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import(
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
export class MyClass implements predom.JSX.Element {
|
||||
__predomBrand!: void;
|
||||
__predomBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>
|
||||
@@ -92,7 +92,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import(
|
||||
const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{props.children}</p>;
|
||||
|
||||
class DOMClass implements dom.JSX.Element {
|
||||
__domBrand!: void;
|
||||
__domBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}</p>;
|
||||
|
||||
@@ -7,7 +7,7 @@ export namespace dom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -27,7 +27,7 @@ export namespace predom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -47,7 +47,7 @@ import { predom } from "./renderer2"
|
||||
export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{...this.props.children}</p>;
|
||||
|
||||
export class MyClass implements predom.JSX.Element {
|
||||
__predomBrand!: void;
|
||||
__predomBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>
|
||||
@@ -70,7 +70,7 @@ elem = <h></h>; // Expect assignability error here
|
||||
const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{props.children}</p>;
|
||||
|
||||
class DOMClass implements dom.JSX.Element {
|
||||
__domBrand!: void;
|
||||
__domBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}</p>;
|
||||
|
||||
@@ -14,11 +14,11 @@ export namespace dom {
|
||||
interface Element {
|
||||
>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
|
||||
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27))
|
||||
|
||||
props: {
|
||||
>props : Symbol(Element.props, Decl(renderer.d.ts, 6, 29))
|
||||
>props : Symbol(Element.props, Decl(renderer.d.ts, 6, 30))
|
||||
|
||||
children?: Element[];
|
||||
>children : Symbol(children, Decl(renderer.d.ts, 7, 20))
|
||||
@@ -65,11 +65,11 @@ export namespace predom {
|
||||
interface Element {
|
||||
>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
|
||||
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27))
|
||||
|
||||
props: {
|
||||
>props : Symbol(Element.props, Decl(renderer2.d.ts, 6, 32))
|
||||
>props : Symbol(Element.props, Decl(renderer2.d.ts, 6, 33))
|
||||
|
||||
children?: Element[];
|
||||
>children : Symbol(children, Decl(renderer2.d.ts, 7, 20))
|
||||
@@ -137,7 +137,7 @@ export class MyClass implements predom.JSX.Element {
|
||||
>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
|
||||
>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
|
||||
|
||||
__predomBrand!: void;
|
||||
__predomBrand!: never;
|
||||
>__predomBrand : Symbol(MyClass.__predomBrand, Decl(component.tsx, 5, 52))
|
||||
|
||||
constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
|
||||
@@ -260,7 +260,7 @@ class DOMClass implements dom.JSX.Element {
|
||||
>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
|
||||
>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
|
||||
|
||||
__domBrand!: void;
|
||||
__domBrand!: never;
|
||||
>__domBrand : Symbol(DOMClass.__domBrand, Decl(index.tsx, 8, 43))
|
||||
|
||||
constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
|
||||
|
||||
@@ -6,8 +6,8 @@ export namespace dom {
|
||||
>e : string
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
>__domBrand : void
|
||||
__domBrand: never;
|
||||
>__domBrand : never
|
||||
|
||||
props: {
|
||||
>props : { children?: Element[]; }
|
||||
@@ -41,8 +41,8 @@ export namespace predom {
|
||||
>e : string
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
>__predomBrand : void
|
||||
__predomBrand: never;
|
||||
>__predomBrand : never
|
||||
|
||||
props: {
|
||||
>props : { children?: Element[]; }
|
||||
@@ -110,8 +110,8 @@ export class MyClass implements predom.JSX.Element {
|
||||
>predom : () => predom.JSX.Element
|
||||
>JSX : any
|
||||
|
||||
__predomBrand!: void;
|
||||
>__predomBrand : void
|
||||
__predomBrand!: never;
|
||||
>__predomBrand : never
|
||||
|
||||
constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
|
||||
>props : { x: number; y: number; children?: predom.JSX.Element[]; }
|
||||
@@ -246,8 +246,8 @@ class DOMClass implements dom.JSX.Element {
|
||||
>dom : () => dom.JSX.Element
|
||||
>JSX : any
|
||||
|
||||
__domBrand!: void;
|
||||
>__domBrand : void
|
||||
__domBrand!: never;
|
||||
>__domBrand : never
|
||||
|
||||
constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
|
||||
>props : { x: number; y: number; children?: dom.JSX.Element[]; }
|
||||
|
||||
@@ -8,7 +8,7 @@ tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__pre
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
@@ -24,7 +24,7 @@ tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__pre
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ declare global {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export namespace predom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ declare global {
|
||||
interface Element {
|
||||
>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
|
||||
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27))
|
||||
|
||||
children: Element[];
|
||||
>children : Symbol(Element.children, Decl(renderer.d.ts, 6, 29))
|
||||
>children : Symbol(Element.children, Decl(renderer.d.ts, 6, 30))
|
||||
>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
|
||||
|
||||
props: {};
|
||||
@@ -54,11 +54,11 @@ export namespace predom {
|
||||
interface Element {
|
||||
>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
|
||||
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27))
|
||||
|
||||
children: Element[];
|
||||
>children : Symbol(Element.children, Decl(renderer2.d.ts, 6, 32))
|
||||
>children : Symbol(Element.children, Decl(renderer2.d.ts, 6, 33))
|
||||
>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
|
||||
|
||||
props: {};
|
||||
|
||||
@@ -8,8 +8,8 @@ declare global {
|
||||
>e : string
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
>__domBrand : void
|
||||
__domBrand: never;
|
||||
>__domBrand : never
|
||||
|
||||
children: Element[];
|
||||
>children : Element[]
|
||||
@@ -36,8 +36,8 @@ export namespace predom {
|
||||
>e : string
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
>__predomBrand : void
|
||||
__predomBrand: never;
|
||||
>__predomBrand : never
|
||||
|
||||
children: Element[];
|
||||
>children : Element[]
|
||||
|
||||
@@ -264,9 +264,9 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c
|
||||
i4 = i2; // Ok
|
||||
i4 = i3; // Ok
|
||||
|
||||
interface Animal { animal: void }
|
||||
interface Dog extends Animal { dog: void }
|
||||
interface Cat extends Animal { cat: void }
|
||||
interface Animal { animal: never }
|
||||
interface Dog extends Animal { dog: never }
|
||||
interface Cat extends Animal { cat: never }
|
||||
|
||||
interface Comparer1<T> {
|
||||
compare(a: T, b: T): number;
|
||||
|
||||
@@ -88,9 +88,9 @@ i4 = i1; // Ok
|
||||
i4 = i2; // Ok
|
||||
i4 = i3; // Ok
|
||||
|
||||
interface Animal { animal: void }
|
||||
interface Dog extends Animal { dog: void }
|
||||
interface Cat extends Animal { cat: void }
|
||||
interface Animal { animal: never }
|
||||
interface Dog extends Animal { dog: never }
|
||||
interface Cat extends Animal { cat: never }
|
||||
|
||||
interface Comparer1<T> {
|
||||
compare(a: T, b: T): number;
|
||||
|
||||
@@ -290,22 +290,22 @@ i4 = i3; // Ok
|
||||
>i4 : Symbol(i4, Decl(strictFunctionTypesErrors.ts, 71, 11))
|
||||
>i3 : Symbol(i3, Decl(strictFunctionTypesErrors.ts, 70, 11))
|
||||
|
||||
interface Animal { animal: void }
|
||||
interface Animal { animal: never }
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
>animal : Symbol(Animal.animal, Decl(strictFunctionTypesErrors.ts, 89, 18))
|
||||
|
||||
interface Dog extends Animal { dog: void }
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
interface Dog extends Animal { dog: never }
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
>dog : Symbol(Dog.dog, Decl(strictFunctionTypesErrors.ts, 90, 30))
|
||||
|
||||
interface Cat extends Animal { cat: void }
|
||||
>Cat : Symbol(Cat, Decl(strictFunctionTypesErrors.ts, 90, 42))
|
||||
interface Cat extends Animal { cat: never }
|
||||
>Cat : Symbol(Cat, Decl(strictFunctionTypesErrors.ts, 90, 43))
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
>cat : Symbol(Cat.cat, Decl(strictFunctionTypesErrors.ts, 91, 30))
|
||||
|
||||
interface Comparer1<T> {
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42))
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 43))
|
||||
>T : Symbol(T, Decl(strictFunctionTypesErrors.ts, 93, 20))
|
||||
|
||||
compare(a: T, b: T): number;
|
||||
@@ -318,13 +318,13 @@ interface Comparer1<T> {
|
||||
|
||||
declare let animalComparer1: Comparer1<Animal>;
|
||||
>animalComparer1 : Symbol(animalComparer1, Decl(strictFunctionTypesErrors.ts, 97, 11))
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42))
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 43))
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
|
||||
declare let dogComparer1: Comparer1<Dog>;
|
||||
>dogComparer1 : Symbol(dogComparer1, Decl(strictFunctionTypesErrors.ts, 98, 11))
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 42))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Comparer1 : Symbol(Comparer1, Decl(strictFunctionTypesErrors.ts, 91, 43))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
|
||||
animalComparer1 = dogComparer1; // Ok
|
||||
>animalComparer1 : Symbol(animalComparer1, Decl(strictFunctionTypesErrors.ts, 97, 11))
|
||||
@@ -354,7 +354,7 @@ declare let animalComparer2: Comparer2<Animal>;
|
||||
declare let dogComparer2: Comparer2<Dog>;
|
||||
>dogComparer2 : Symbol(dogComparer2, Decl(strictFunctionTypesErrors.ts, 108, 11))
|
||||
>Comparer2 : Symbol(Comparer2, Decl(strictFunctionTypesErrors.ts, 101, 31))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
|
||||
animalComparer2 = dogComparer2; // Error
|
||||
>animalComparer2 : Symbol(animalComparer2, Decl(strictFunctionTypesErrors.ts, 107, 11))
|
||||
@@ -388,7 +388,7 @@ declare let animalCrate: Crate<Animal>;
|
||||
declare let dogCrate: Crate<Dog>;
|
||||
>dogCrate : Symbol(dogCrate, Decl(strictFunctionTypesErrors.ts, 121, 11))
|
||||
>Crate : Symbol(Crate, Decl(strictFunctionTypesErrors.ts, 111, 31))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
|
||||
// Errors below should elaborate the reason for invariance
|
||||
|
||||
@@ -413,8 +413,8 @@ declare let fc2: (f: (x: Dog) => Dog) => void;
|
||||
>fc2 : Symbol(fc2, Decl(strictFunctionTypesErrors.ts, 131, 11))
|
||||
>f : Symbol(f, Decl(strictFunctionTypesErrors.ts, 131, 18))
|
||||
>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 131, 22))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
|
||||
fc1 = fc2; // Error
|
||||
>fc1 : Symbol(fc1, Decl(strictFunctionTypesErrors.ts, 130, 11))
|
||||
@@ -442,7 +442,7 @@ namespace n1 {
|
||||
static f2(x: Dog): Animal { throw "wat"; };
|
||||
>f2 : Symbol(Foo.f2, Decl(strictFunctionTypesErrors.ts, 140, 53))
|
||||
>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 141, 18))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
}
|
||||
declare let f1: (cb: typeof Foo.f1) => void;
|
||||
@@ -491,7 +491,7 @@ namespace n2 {
|
||||
>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 152, 15))
|
||||
>cb : Symbol(cb, Decl(strictFunctionTypesErrors.ts, 152, 21))
|
||||
>BivariantHack : Symbol(BivariantHack, Decl(strictFunctionTypesErrors.ts, 149, 14))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
|
||||
>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 34))
|
||||
>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
|
||||
|
||||
f1 = f2;
|
||||
|
||||
@@ -298,14 +298,14 @@ i4 = i3; // Ok
|
||||
>i4 : Func<string, Func<string, void>>
|
||||
>i3 : Func<string, Func<Object, void>>
|
||||
|
||||
interface Animal { animal: void }
|
||||
>animal : void
|
||||
interface Animal { animal: never }
|
||||
>animal : never
|
||||
|
||||
interface Dog extends Animal { dog: void }
|
||||
>dog : void
|
||||
interface Dog extends Animal { dog: never }
|
||||
>dog : never
|
||||
|
||||
interface Cat extends Animal { cat: void }
|
||||
>cat : void
|
||||
interface Cat extends Animal { cat: never }
|
||||
>cat : never
|
||||
|
||||
interface Comparer1<T> {
|
||||
compare(a: T, b: T): number;
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(16,1): error TS2322: Type 'X<void>' is not assignable to type 'X<number>'.
|
||||
Type 'void' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(17,1): error TS2322: Type 'X<number | void>' is not assignable to type 'X<number>'.
|
||||
Type 'number | void' is not assignable to type 'number'.
|
||||
Type 'void' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(18,1): error TS2322: Type 'Y<number>' is not assignable to type 'X<number>'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'number | undefined' is not assignable to type 'number'.
|
||||
Type 'undefined' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(19,1): error TS2741: Property 'value' is missing in type '{ done: true; }' but required in type 'X<number>'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(21,19): error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(22,19): error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(23,19): error TS2322: Type 'void' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(25,1): error TS2322: Type 'X<number>' is not assignable to type 'X<void>'.
|
||||
Type 'number' is not assignable to type 'void'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(26,1): error TS2322: Type 'X<number | void>' is not assignable to type 'X<void>'.
|
||||
Type 'number | void' is not assignable to type 'void'.
|
||||
Type 'number' is not assignable to type 'void'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(27,1): error TS2322: Type 'Y<number>' is not assignable to type 'X<void>'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'number | undefined' is not assignable to type 'void'.
|
||||
Type 'number' is not assignable to type 'void'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(29,19): error TS2322: Type 'number' is not assignable to type 'void'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(44,1): error TS2322: Type 'X<void>' is not assignable to type 'Y<number>'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'void' is not assignable to type 'number | undefined'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(45,1): error TS2322: Type 'X<number | void>' is not assignable to type 'Y<number>'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'number | void' is not assignable to type 'number | undefined'.
|
||||
Type 'void' is not assignable to type 'number | undefined'.
|
||||
tests/cases/conformance/types/members/typesWithVoidProperty.ts(50,19): error TS2322: Type 'void' is not assignable to type 'number | undefined'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/members/typesWithVoidProperty.ts (14 errors) ====
|
||||
interface X<T> {
|
||||
done: true;
|
||||
value: T;
|
||||
}
|
||||
|
||||
interface Y<T> {
|
||||
done: true;
|
||||
value?: T;
|
||||
}
|
||||
|
||||
declare let a: X<number>;
|
||||
declare let b: X<void>;
|
||||
declare let c: X<number | void>;
|
||||
declare let d: Y<number>;
|
||||
|
||||
a = b; // not allowed because `value` must be `number`
|
||||
~
|
||||
!!! error TS2322: Type 'X<void>' is not assignable to type 'X<number>'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number'.
|
||||
a = c; // not allowed because `value` must be `number`
|
||||
~
|
||||
!!! error TS2322: Type 'X<number | void>' is not assignable to type 'X<number>'.
|
||||
!!! error TS2322: Type 'number | void' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number'.
|
||||
a = d; // not allowed because `value` must be `number`
|
||||
~
|
||||
!!! error TS2322: Type 'Y<number>' is not assignable to type 'X<number>'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
a = { done: true }; // not allowed because `value` is not optional (non-`void`)
|
||||
~
|
||||
!!! error TS2741: Property 'value' is missing in type '{ done: true; }' but required in type 'X<number>'.
|
||||
!!! related TS2728 tests/cases/conformance/types/members/typesWithVoidProperty.ts:3:5: 'value' is declared here.
|
||||
a = { done: true, value: 1 }; // allowed because `value` must be `number`
|
||||
a = { done: true, value: undefined }; // not allowed because `value` must be `number`
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
!!! related TS6500 tests/cases/conformance/types/members/typesWithVoidProperty.ts:3:5: The expected type comes from property 'value' which is declared here on type 'X<number>'
|
||||
a = { done: true, value: undefined as undefined }; // not allowed because `value` must be `number`
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
!!! related TS6500 tests/cases/conformance/types/members/typesWithVoidProperty.ts:3:5: The expected type comes from property 'value' which is declared here on type 'X<number>'
|
||||
a = { done: true, value: undefined as void }; // not allowed because `value` must be `number`
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number'.
|
||||
!!! related TS6500 tests/cases/conformance/types/members/typesWithVoidProperty.ts:3:5: The expected type comes from property 'value' which is declared here on type 'X<number>'
|
||||
|
||||
b = a; // not allowed because `value` must be `void`
|
||||
~
|
||||
!!! error TS2322: Type 'X<number>' is not assignable to type 'X<void>'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'void'.
|
||||
b = c; // not allowed because `value` must be `void`
|
||||
~
|
||||
!!! error TS2322: Type 'X<number | void>' is not assignable to type 'X<void>'.
|
||||
!!! error TS2322: Type 'number | void' is not assignable to type 'void'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'void'.
|
||||
b = d; // not allowed because `value` must be `void`
|
||||
~
|
||||
!!! error TS2322: Type 'Y<number>' is not assignable to type 'X<void>'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'number | undefined' is not assignable to type 'void'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'void'.
|
||||
b = { done: true }; // allowed because `value` is optional due to `void`
|
||||
b = { done: true, value: 1 }; // not allowed because `value` must be `void`
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'void'.
|
||||
!!! related TS6500 tests/cases/conformance/types/members/typesWithVoidProperty.ts:3:5: The expected type comes from property 'value' which is declared here on type 'X<void>'
|
||||
b = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
b = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
b = { done: true, value: undefined as void }; // allowed because `value` must be `void`
|
||||
|
||||
c = a; // allowed because `value` can be `number`
|
||||
c = b; // allowed because `value` can be `void`
|
||||
c = d; // allowed because `value` can be `undefined`
|
||||
c = { done: true }; // allowed because `value` is optional due to `void`
|
||||
c = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
c = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
c = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
c = { done: true, value: undefined as void }; // allowed because `value` can be `void`
|
||||
|
||||
d = a; // allowed because `value` must be `number | void`
|
||||
d = b; // not allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
~
|
||||
!!! error TS2322: Type 'X<void>' is not assignable to type 'Y<number>'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number | undefined'.
|
||||
d = c; // not allowed allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
~
|
||||
!!! error TS2322: Type 'X<number | void>' is not assignable to type 'Y<number>'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'number | void' is not assignable to type 'number | undefined'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number | undefined'.
|
||||
d = { done: true }; // allowed because `value` is optional
|
||||
d = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
d = { done: true, value: undefined }; // allowed because `value` can be `undefined`
|
||||
d = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined`
|
||||
d = { done: true, value: undefined as void }; // not allowed because `value` can be `undefined`, and `void` is a supertype of `undefined
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number | undefined'.
|
||||
!!! related TS6500 tests/cases/conformance/types/members/typesWithVoidProperty.ts:8:5: The expected type comes from property 'value' which is declared here on type 'Y<number>'
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
=== tests/cases/conformance/types/members/typesWithVoidProperty.ts ===
|
||||
interface X<T> {
|
||||
>X : Symbol(X, Decl(typesWithVoidProperty.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(typesWithVoidProperty.ts, 0, 12))
|
||||
|
||||
done: true;
|
||||
>done : Symbol(X.done, Decl(typesWithVoidProperty.ts, 0, 16))
|
||||
|
||||
value: T;
|
||||
>value : Symbol(X.value, Decl(typesWithVoidProperty.ts, 1, 15))
|
||||
>T : Symbol(T, Decl(typesWithVoidProperty.ts, 0, 12))
|
||||
}
|
||||
|
||||
interface Y<T> {
|
||||
>Y : Symbol(Y, Decl(typesWithVoidProperty.ts, 3, 1))
|
||||
>T : Symbol(T, Decl(typesWithVoidProperty.ts, 5, 12))
|
||||
|
||||
done: true;
|
||||
>done : Symbol(Y.done, Decl(typesWithVoidProperty.ts, 5, 16))
|
||||
|
||||
value?: T;
|
||||
>value : Symbol(Y.value, Decl(typesWithVoidProperty.ts, 6, 15))
|
||||
>T : Symbol(T, Decl(typesWithVoidProperty.ts, 5, 12))
|
||||
}
|
||||
|
||||
declare let a: X<number>;
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>X : Symbol(X, Decl(typesWithVoidProperty.ts, 0, 0))
|
||||
|
||||
declare let b: X<void>;
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>X : Symbol(X, Decl(typesWithVoidProperty.ts, 0, 0))
|
||||
|
||||
declare let c: X<number | void>;
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>X : Symbol(X, Decl(typesWithVoidProperty.ts, 0, 0))
|
||||
|
||||
declare let d: Y<number>;
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>Y : Symbol(Y, Decl(typesWithVoidProperty.ts, 3, 1))
|
||||
|
||||
a = b; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
|
||||
a = c; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
|
||||
a = d; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
|
||||
a = { done: true }; // not allowed because `value` is not optional (non-`void`)
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 18, 5))
|
||||
|
||||
a = { done: true, value: 1 }; // allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 19, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 19, 17))
|
||||
|
||||
a = { done: true, value: undefined }; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 20, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 20, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
a = { done: true, value: undefined as undefined }; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 21, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 21, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
a = { done: true, value: undefined as void }; // not allowed because `value` must be `number`
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 22, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 22, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
b = a; // not allowed because `value` must be `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
|
||||
b = c; // not allowed because `value` must be `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
|
||||
b = d; // not allowed because `value` must be `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
|
||||
b = { done: true }; // allowed because `value` is optional due to `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 27, 5))
|
||||
|
||||
b = { done: true, value: 1 }; // not allowed because `value` must be `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 28, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 28, 17))
|
||||
|
||||
b = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 29, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 29, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
b = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 30, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 30, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
b = { done: true, value: undefined as void }; // allowed because `value` must be `void`
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 31, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 31, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
c = a; // allowed because `value` can be `number`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
|
||||
c = b; // allowed because `value` can be `void`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
|
||||
c = d; // allowed because `value` can be `undefined`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
|
||||
c = { done: true }; // allowed because `value` is optional due to `void`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 36, 5))
|
||||
|
||||
c = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 37, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 37, 17))
|
||||
|
||||
c = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 38, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 38, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
c = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 39, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 39, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
c = { done: true, value: undefined as void }; // allowed because `value` can be `void`
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 40, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 40, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
d = a; // allowed because `value` must be `number | void`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>a : Symbol(a, Decl(typesWithVoidProperty.ts, 10, 11))
|
||||
|
||||
d = b; // not allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>b : Symbol(b, Decl(typesWithVoidProperty.ts, 11, 11))
|
||||
|
||||
d = c; // not allowed allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>c : Symbol(c, Decl(typesWithVoidProperty.ts, 12, 11))
|
||||
|
||||
d = { done: true }; // allowed because `value` is optional
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 45, 5))
|
||||
|
||||
d = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 46, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 46, 17))
|
||||
|
||||
d = { done: true, value: undefined }; // allowed because `value` can be `undefined`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 47, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 47, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
d = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined`
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 48, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 48, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
d = { done: true, value: undefined as void }; // not allowed because `value` can be `undefined`, and `void` is a supertype of `undefined
|
||||
>d : Symbol(d, Decl(typesWithVoidProperty.ts, 13, 11))
|
||||
>done : Symbol(done, Decl(typesWithVoidProperty.ts, 49, 5))
|
||||
>value : Symbol(value, Decl(typesWithVoidProperty.ts, 49, 17))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
=== tests/cases/conformance/types/members/typesWithVoidProperty.ts ===
|
||||
interface X<T> {
|
||||
done: true;
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
value: T;
|
||||
>value : T
|
||||
}
|
||||
|
||||
interface Y<T> {
|
||||
done: true;
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
value?: T;
|
||||
>value : T | undefined
|
||||
}
|
||||
|
||||
declare let a: X<number>;
|
||||
>a : X<number>
|
||||
|
||||
declare let b: X<void>;
|
||||
>b : X<void>
|
||||
|
||||
declare let c: X<number | void>;
|
||||
>c : X<number | void>
|
||||
|
||||
declare let d: Y<number>;
|
||||
>d : Y<number>
|
||||
|
||||
a = b; // not allowed because `value` must be `number`
|
||||
>a = b : X<void>
|
||||
>a : X<number>
|
||||
>b : X<void>
|
||||
|
||||
a = c; // not allowed because `value` must be `number`
|
||||
>a = c : X<number | void>
|
||||
>a : X<number>
|
||||
>c : X<number | void>
|
||||
|
||||
a = d; // not allowed because `value` must be `number`
|
||||
>a = d : Y<number>
|
||||
>a : X<number>
|
||||
>d : Y<number>
|
||||
|
||||
a = { done: true }; // not allowed because `value` is not optional (non-`void`)
|
||||
>a = { done: true } : { done: true; }
|
||||
>a : X<number>
|
||||
>{ done: true } : { done: true; }
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
a = { done: true, value: 1 }; // allowed because `value` must be `number`
|
||||
>a = { done: true, value: 1 } : { done: true; value: number; }
|
||||
>a : X<number>
|
||||
>{ done: true, value: 1 } : { done: true; value: number; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : number
|
||||
>1 : 1
|
||||
|
||||
a = { done: true, value: undefined }; // not allowed because `value` must be `number`
|
||||
>a = { done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>a : X<number>
|
||||
>{ done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined : undefined
|
||||
|
||||
a = { done: true, value: undefined as undefined }; // not allowed because `value` must be `number`
|
||||
>a = { done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>a : X<number>
|
||||
>{ done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined as undefined : undefined
|
||||
>undefined : undefined
|
||||
|
||||
a = { done: true, value: undefined as void }; // not allowed because `value` must be `number`
|
||||
>a = { done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>a : X<number>
|
||||
>{ done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : void
|
||||
>undefined as void : void
|
||||
>undefined : undefined
|
||||
|
||||
b = a; // not allowed because `value` must be `void`
|
||||
>b = a : X<number>
|
||||
>b : X<void>
|
||||
>a : X<number>
|
||||
|
||||
b = c; // not allowed because `value` must be `void`
|
||||
>b = c : X<number | void>
|
||||
>b : X<void>
|
||||
>c : X<number | void>
|
||||
|
||||
b = d; // not allowed because `value` must be `void`
|
||||
>b = d : Y<number>
|
||||
>b : X<void>
|
||||
>d : Y<number>
|
||||
|
||||
b = { done: true }; // allowed because `value` is optional due to `void`
|
||||
>b = { done: true } : { done: true; }
|
||||
>b : X<void>
|
||||
>{ done: true } : { done: true; }
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
b = { done: true, value: 1 }; // not allowed because `value` must be `void`
|
||||
>b = { done: true, value: 1 } : { done: true; value: number; }
|
||||
>b : X<void>
|
||||
>{ done: true, value: 1 } : { done: true; value: number; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : number
|
||||
>1 : 1
|
||||
|
||||
b = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>b = { done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>b : X<void>
|
||||
>{ done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined : undefined
|
||||
|
||||
b = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>b = { done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>b : X<void>
|
||||
>{ done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined as undefined : undefined
|
||||
>undefined : undefined
|
||||
|
||||
b = { done: true, value: undefined as void }; // allowed because `value` must be `void`
|
||||
>b = { done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>b : X<void>
|
||||
>{ done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : void
|
||||
>undefined as void : void
|
||||
>undefined : undefined
|
||||
|
||||
c = a; // allowed because `value` can be `number`
|
||||
>c = a : X<number>
|
||||
>c : X<number | void>
|
||||
>a : X<number>
|
||||
|
||||
c = b; // allowed because `value` can be `void`
|
||||
>c = b : X<void>
|
||||
>c : X<number | void>
|
||||
>b : X<void>
|
||||
|
||||
c = d; // allowed because `value` can be `undefined`
|
||||
>c = d : Y<number>
|
||||
>c : X<number | void>
|
||||
>d : Y<number>
|
||||
|
||||
c = { done: true }; // allowed because `value` is optional due to `void`
|
||||
>c = { done: true } : { done: true; }
|
||||
>c : X<number | void>
|
||||
>{ done: true } : { done: true; }
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
c = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
>c = { done: true, value: 1 } : { done: true; value: number; }
|
||||
>c : X<number | void>
|
||||
>{ done: true, value: 1 } : { done: true; value: number; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : number
|
||||
>1 : 1
|
||||
|
||||
c = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>c = { done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>c : X<number | void>
|
||||
>{ done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined : undefined
|
||||
|
||||
c = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
>c = { done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>c : X<number | void>
|
||||
>{ done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined as undefined : undefined
|
||||
>undefined : undefined
|
||||
|
||||
c = { done: true, value: undefined as void }; // allowed because `value` can be `void`
|
||||
>c = { done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>c : X<number | void>
|
||||
>{ done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : void
|
||||
>undefined as void : void
|
||||
>undefined : undefined
|
||||
|
||||
d = a; // allowed because `value` must be `number | void`
|
||||
>d = a : X<number>
|
||||
>d : Y<number>
|
||||
>a : X<number>
|
||||
|
||||
d = b; // not allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
>d = b : X<void>
|
||||
>d : Y<number>
|
||||
>b : X<void>
|
||||
|
||||
d = c; // not allowed allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
>d = c : X<number | void>
|
||||
>d : Y<number>
|
||||
>c : X<number | void>
|
||||
|
||||
d = { done: true }; // allowed because `value` is optional
|
||||
>d = { done: true } : { done: true; }
|
||||
>d : Y<number>
|
||||
>{ done: true } : { done: true; }
|
||||
>done : true
|
||||
>true : true
|
||||
|
||||
d = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
>d = { done: true, value: 1 } : { done: true; value: number; }
|
||||
>d : Y<number>
|
||||
>{ done: true, value: 1 } : { done: true; value: number; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : number
|
||||
>1 : 1
|
||||
|
||||
d = { done: true, value: undefined }; // allowed because `value` can be `undefined`
|
||||
>d = { done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>d : Y<number>
|
||||
>{ done: true, value: undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined : undefined
|
||||
|
||||
d = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined`
|
||||
>d = { done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>d : Y<number>
|
||||
>{ done: true, value: undefined as undefined } : { done: true; value: undefined; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : undefined
|
||||
>undefined as undefined : undefined
|
||||
>undefined : undefined
|
||||
|
||||
d = { done: true, value: undefined as void }; // not allowed because `value` can be `undefined`, and `void` is a supertype of `undefined
|
||||
>d = { done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>d : Y<number>
|
||||
>{ done: true, value: undefined as void } : { done: true; value: void; }
|
||||
>done : true
|
||||
>true : true
|
||||
>value : void
|
||||
>undefined as void : void
|
||||
>undefined : undefined
|
||||
|
||||
@@ -88,9 +88,9 @@ i4 = i1; // Ok
|
||||
i4 = i2; // Ok
|
||||
i4 = i3; // Ok
|
||||
|
||||
interface Animal { animal: void }
|
||||
interface Dog extends Animal { dog: void }
|
||||
interface Cat extends Animal { cat: void }
|
||||
interface Animal { animal: never }
|
||||
interface Dog extends Animal { dog: never }
|
||||
interface Cat extends Animal { cat: never }
|
||||
|
||||
interface Comparer1<T> {
|
||||
compare(a: T, b: T): number;
|
||||
|
||||
@@ -6,7 +6,7 @@ export namespace dom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -26,7 +26,7 @@ export namespace predom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
props: {
|
||||
children?: Element[];
|
||||
};
|
||||
@@ -46,7 +46,7 @@ import { predom } from "./renderer2"
|
||||
export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{...this.props.children}</p>;
|
||||
|
||||
export class MyClass implements predom.JSX.Element {
|
||||
__predomBrand!: void;
|
||||
__predomBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>
|
||||
@@ -69,7 +69,7 @@ elem = <h></h>; // Expect assignability error here
|
||||
const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{props.children}</p>;
|
||||
|
||||
class DOMClass implements dom.JSX.Element {
|
||||
__domBrand!: void;
|
||||
__domBrand!: never;
|
||||
constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
|
||||
render() {
|
||||
return <p>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}</p>;
|
||||
|
||||
@@ -6,7 +6,7 @@ declare global {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__domBrand: void;
|
||||
__domBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
@@ -22,7 +22,7 @@ export namespace predom {
|
||||
[e: string]: {};
|
||||
}
|
||||
interface Element {
|
||||
__predomBrand: void;
|
||||
__predomBrand: never;
|
||||
children: Element[];
|
||||
props: {};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
interface X<T> {
|
||||
done: true;
|
||||
value: T;
|
||||
}
|
||||
|
||||
interface Y<T> {
|
||||
done: true;
|
||||
value?: T;
|
||||
}
|
||||
|
||||
declare let a: X<number>;
|
||||
declare let b: X<void>;
|
||||
declare let c: X<number | void>;
|
||||
declare let d: Y<number>;
|
||||
|
||||
a = b; // not allowed because `value` must be `number`
|
||||
a = c; // not allowed because `value` must be `number`
|
||||
a = d; // not allowed because `value` must be `number`
|
||||
a = { done: true }; // not allowed because `value` is not optional (non-`void`)
|
||||
a = { done: true, value: 1 }; // allowed because `value` must be `number`
|
||||
a = { done: true, value: undefined }; // not allowed because `value` must be `number`
|
||||
a = { done: true, value: undefined as undefined }; // not allowed because `value` must be `number`
|
||||
a = { done: true, value: undefined as void }; // not allowed because `value` must be `number`
|
||||
|
||||
b = a; // not allowed because `value` must be `void`
|
||||
b = c; // not allowed because `value` must be `void`
|
||||
b = d; // not allowed because `value` must be `void`
|
||||
b = { done: true }; // allowed because `value` is optional due to `void`
|
||||
b = { done: true, value: 1 }; // not allowed because `value` must be `void`
|
||||
b = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
b = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
b = { done: true, value: undefined as void }; // allowed because `value` must be `void`
|
||||
|
||||
c = a; // allowed because `value` can be `number`
|
||||
c = b; // allowed because `value` can be `void`
|
||||
c = d; // allowed because `value` can be `undefined`
|
||||
c = { done: true }; // allowed because `value` is optional due to `void`
|
||||
c = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
c = { done: true, value: undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
c = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined` (assignable to `void`)
|
||||
c = { done: true, value: undefined as void }; // allowed because `value` can be `void`
|
||||
|
||||
d = a; // allowed because `value` must be `number | void`
|
||||
d = b; // not allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
d = c; // not allowed allowed because `value` must be `undefined`, and `void` is a supertype of `undefined`
|
||||
d = { done: true }; // allowed because `value` is optional
|
||||
d = { done: true, value: 1 }; // allowed because `value` can be `number`
|
||||
d = { done: true, value: undefined }; // allowed because `value` can be `undefined`
|
||||
d = { done: true, value: undefined as undefined }; // allowed because `value` can be `undefined`
|
||||
d = { done: true, value: undefined as void }; // not allowed because `value` can be `undefined`, and `void` is a supertype of `undefined
|
||||
Reference in New Issue
Block a user