Compare commits
14 commits
main
...
difference
Author | SHA1 | Date | |
---|---|---|---|
a47fb274ad | |||
55d8dcfc3d | |||
813e2352dc | |||
bd24964b9c | |||
fd368284c6 | |||
330ea37603 | |||
24c5d86902 | |||
d8b25a4371 | |||
f9ec6aa296 | |||
2119d59a11 | |||
d935cdbad1 | |||
6897baaba2 | |||
f11b07f976 | |||
8eb9e93b48 |
|
@ -124,6 +124,7 @@ namespace ts {
|
|||
const tupleTypes: GenericType[] = [];
|
||||
const unionTypes = createMap<UnionType>();
|
||||
const intersectionTypes = createMap<IntersectionType>();
|
||||
const differenceTypes = createMap<DifferenceType>();
|
||||
const stringLiteralTypes = createMap<LiteralType>();
|
||||
const numericLiteralTypes = createMap<LiteralType>();
|
||||
const indexedAccessTypes = createMap<IndexedAccessType>();
|
||||
|
@ -2321,6 +2322,9 @@ namespace ts {
|
|||
else if (type.flags & TypeFlags.UnionOrIntersection) {
|
||||
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, nextFlags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Difference) {
|
||||
writeDifferenceType(type as DifferenceType, nextFlags);
|
||||
}
|
||||
else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) {
|
||||
writeAnonymousType(<ObjectType>type, nextFlags);
|
||||
}
|
||||
|
@ -2436,6 +2440,16 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function writeDifferenceType(type: DifferenceType, flags: TypeFormatFlags) {
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenParenToken);
|
||||
}
|
||||
writeTypeList([type.source, type.remove], SyntaxKind.MinusToken);
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
writePunctuation(writer, SyntaxKind.CloseParenToken);
|
||||
}
|
||||
}
|
||||
|
||||
function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) {
|
||||
const symbol = type.symbol;
|
||||
if (symbol) {
|
||||
|
@ -4828,13 +4842,18 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getApparentTypeOfDifference(type: DifferenceType) {
|
||||
return getDifferenceType(getApparentType(type.source), getApparentType(type.remove));
|
||||
}
|
||||
|
||||
/**
|
||||
* For a type parameter, return the base constraint of the type parameter. For the string, number,
|
||||
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
|
||||
* type itself. Note that the apparent type of a union type is the union type itself.
|
||||
*/
|
||||
function getApparentType(type: Type): Type {
|
||||
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfTypeVariable(<TypeVariable>type) || emptyObjectType : type;
|
||||
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfTypeVariable(<TypeVariable>type) || emptyObjectType :
|
||||
type.flags & TypeFlags.Difference ? getApparentTypeOfDifference(type as DifferenceType) : type;
|
||||
return t.flags & TypeFlags.StringLike ? globalStringType :
|
||||
t.flags & TypeFlags.NumberLike ? globalNumberType :
|
||||
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
|
||||
|
@ -6028,6 +6047,54 @@ namespace ts {
|
|||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromDifferenceTypeNode(node: DifferenceTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getDifferenceType(getTypeFromTypeNode(node.source), getTypeFromTypeNode(node.remove));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getDifferenceType(source: Type, remove: Type) {
|
||||
//TOOD: Handle any here (if source is any, the result is any; if remove is any, the result is never. or any?!)
|
||||
if (source.flags & TypeFlags.Any || remove.flags & TypeFlags.Any) {
|
||||
return anyType;
|
||||
}
|
||||
const id = getTypeListId([source, remove]);
|
||||
if (id in differenceTypes) {
|
||||
return differenceTypes[id];
|
||||
}
|
||||
// TODO: Simplifications first (intersection distributes over difference)
|
||||
// if left and right are both string literal union, then return the removal of right's contents from left's
|
||||
// TODO: Probably should delay or paper over this check, but whatever. I'll write it for now.
|
||||
if (isStringLiteralUnion(source) && remove.flags & TypeFlags.StringLiteral) {
|
||||
return filterType(source, t => t !== remove);
|
||||
}
|
||||
if (isStringLiteralUnion(source) && isStringLiteralUnion(remove)) {
|
||||
return filterType(source, t => (remove as UnionType).types.indexOf(t) === -1);
|
||||
}
|
||||
|
||||
// if either left or right is a type parameter, then return a difference type
|
||||
// TODO: Add tests with keyof T
|
||||
if (source.flags & (TypeFlags.TypeParameter | TypeFlags.Index) || remove.flags & (TypeFlags.TypeParameter | TypeFlags.Index)) {
|
||||
const difference = differenceTypes[id] = createType(TypeFlags.Difference) as DifferenceType;
|
||||
difference.source = source;
|
||||
difference.remove = remove;
|
||||
return difference;
|
||||
}
|
||||
// if right is string then return never
|
||||
if ((source.flags & TypeFlags.StringLike || isStringLiteralUnion(source)) && remove.flags & TypeFlags.String) {
|
||||
return neverType;
|
||||
}
|
||||
// otherwise just return source
|
||||
return source;
|
||||
}
|
||||
|
||||
function isStringLiteralUnion(type: Type) {
|
||||
return type.flags & TypeFlags.StringLiteral ||
|
||||
type.flags & TypeFlags.Union && every((type as UnionType).types, t => !!(t.flags & TypeFlags.StringLiteral));
|
||||
}
|
||||
|
||||
function getIndexTypeForGenericType(type: TypeVariable | UnionOrIntersectionType) {
|
||||
if (!type.resolvedIndexType) {
|
||||
type.resolvedIndexType = <IndexType>createType(TypeFlags.Index);
|
||||
|
@ -6444,6 +6511,8 @@ namespace ts {
|
|||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.JSDocUnionType:
|
||||
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
|
||||
case SyntaxKind.DifferenceType:
|
||||
return getTypeFromDifferenceTypeNode(node as DifferenceTypeNode);
|
||||
case SyntaxKind.IntersectionType:
|
||||
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
|
@ -6821,6 +6890,10 @@ namespace ts {
|
|||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Difference) {
|
||||
const difference = type as DifferenceType;
|
||||
return getDifferenceType(instantiateType(difference.source, mapper), instantiateType(difference.remove, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
|
@ -7456,6 +7529,21 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Difference) {
|
||||
if (source.flags & TypeFlags.TypeParameter && (target as DifferenceType).source === source) {
|
||||
return Ternary.True;
|
||||
}
|
||||
else if (source.flags & TypeFlags.Difference) {
|
||||
const srcDiff = source as DifferenceType;
|
||||
const tgtDiff = target as DifferenceType;
|
||||
if ((result = isRelatedTo(srcDiff.source, tgtDiff.source, reportErrors)) === Ternary.False) {
|
||||
return result;
|
||||
}
|
||||
if (result = isRelatedTo(srcDiff.remove, tgtDiff.remove, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
// A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
|
||||
|
@ -16039,6 +16127,21 @@ namespace ts {
|
|||
forEach(node.types, checkSourceElement);
|
||||
}
|
||||
|
||||
function checkDifferenceType(node: DifferenceTypeNode) {
|
||||
const remove = getTypeFromTypeNode(node.remove);
|
||||
if (!(remove.flags & (TypeFlags.Index | TypeFlags.TypeParameter | TypeFlags.String) || isStringLiteralUnion(remove))) {
|
||||
error(node.remove, Diagnostics.The_right_side_of_a_difference_type_must_be_a_string_or_string_literal_union_or_a_type_parameter_constrained_to_one_of_these);
|
||||
}
|
||||
if (remove.flags & TypeFlags.TypeParameter) {
|
||||
const constraint = (remove as TypeParameter).constraint;
|
||||
if (constraint && !(constraint.flags & (TypeFlags.Index | TypeFlags.String) || isStringLiteralUnion(constraint))) {
|
||||
error(node.remove, Diagnostics.The_right_side_of_a_difference_type_must_be_a_string_or_string_literal_union_or_a_type_parameter_constrained_to_one_of_these);
|
||||
}
|
||||
}
|
||||
checkSourceElement(node.source);
|
||||
checkSourceElement(node.remove);
|
||||
}
|
||||
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode) {
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
// Check that the index type is assignable to 'keyof T' for the object type.
|
||||
|
@ -19378,6 +19481,8 @@ namespace ts {
|
|||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.IntersectionType:
|
||||
return checkUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);
|
||||
case SyntaxKind.DifferenceType:
|
||||
return checkDifferenceType(node as DifferenceTypeNode);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||
|
|
|
@ -1174,6 +1174,13 @@ namespace ts {
|
|||
writeLine();
|
||||
}
|
||||
|
||||
function emitDifferenceType(node: DifferenceTypeNode) {
|
||||
emitType(node.source);
|
||||
write("-");
|
||||
emitType(node.remove);
|
||||
writeLine();
|
||||
}
|
||||
|
||||
function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
|
||||
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
|
||||
// so there is no check needed to see if declaration is visible
|
||||
|
@ -1761,6 +1768,8 @@ namespace ts {
|
|||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return emitAccessorDeclaration(<AccessorDeclaration>node);
|
||||
case SyntaxKind.DifferenceType:
|
||||
return emitDifferenceType(node as DifferenceTypeNode);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return emitPropertyDeclaration(<PropertyDeclaration>node);
|
||||
|
|
|
@ -2035,6 +2035,10 @@
|
|||
"category": "Error",
|
||||
"code": 2704
|
||||
},
|
||||
"The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.": {
|
||||
"category": "Error",
|
||||
"code": 2705
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
|
|
@ -135,6 +135,9 @@ namespace ts {
|
|||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.IntersectionType:
|
||||
return visitNodes(cbNodes, (<UnionOrIntersectionTypeNode>node).types);
|
||||
case SyntaxKind.DifferenceType:
|
||||
return visitNode(cbNode, (node as DifferenceTypeNode).source) ||
|
||||
visitNode(cbNode, (node as DifferenceTypeNode).remove);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||
|
@ -2639,7 +2642,25 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function parseIntersectionTypeOrHigher(): TypeNode {
|
||||
function parseDifferenceTypeOrHigher(): TypeNode {
|
||||
let source = parseUnionTypeOrHigher();
|
||||
// create left-associative difference types as long as the parser sees `-`
|
||||
while (token() === SyntaxKind.MinusToken) {
|
||||
parseTokenNode();
|
||||
// not sure which parsing function to call here maybe just parseType? Or parseTypeOperatorOrHigher?
|
||||
source = makeDifferenceType(source, parseType());
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
function makeDifferenceType(source: TypeNode, remove: TypeNode) {
|
||||
const node = createNode(SyntaxKind.DifferenceType, source.pos) as DifferenceTypeNode;
|
||||
node.source = source;
|
||||
node.remove = remove;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseIntersectionTypeOrHigher(): TypeNode {
|
||||
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken);
|
||||
}
|
||||
|
||||
|
@ -2736,7 +2757,7 @@ namespace ts {
|
|||
if (token() === SyntaxKind.NewKeyword) {
|
||||
return parseFunctionOrConstructorType(SyntaxKind.ConstructorType);
|
||||
}
|
||||
return parseUnionTypeOrHigher();
|
||||
return parseDifferenceTypeOrHigher();
|
||||
}
|
||||
|
||||
function parseTypeAnnotation(): TypeNode {
|
||||
|
|
|
@ -216,6 +216,7 @@ namespace ts {
|
|||
TupleType,
|
||||
UnionType,
|
||||
IntersectionType,
|
||||
DifferenceType,
|
||||
ParenthesizedType,
|
||||
ThisType,
|
||||
TypeOperator,
|
||||
|
@ -886,6 +887,12 @@ namespace ts {
|
|||
kind: SyntaxKind.IntersectionType;
|
||||
}
|
||||
|
||||
export interface DifferenceTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.DifferenceType;
|
||||
source: TypeNode;
|
||||
remove: TypeNode;
|
||||
}
|
||||
|
||||
export interface ParenthesizedTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.ParenthesizedType;
|
||||
type: TypeNode;
|
||||
|
@ -2788,6 +2795,7 @@ namespace ts {
|
|||
/* @internal */
|
||||
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
|
||||
NonPrimitive = 1 << 24, // intrinsic object type
|
||||
Difference = 1 << 25, // (keyof T - keyof U)
|
||||
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
|
@ -2932,6 +2940,11 @@ namespace ts {
|
|||
|
||||
export type StructuredType = ObjectType | UnionType | IntersectionType;
|
||||
|
||||
export interface DifferenceType extends Type {
|
||||
source: Type; // both should be index type (keyof T), string or string literal union
|
||||
remove: Type; // or a type parameter constrained to one of those 3 types
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
// An instantiated anonymous type has a target and a mapper
|
||||
export interface AnonymousType extends ObjectType {
|
||||
|
|
47
tests/baselines/reference/differenceType.js
Normal file
47
tests/baselines/reference/differenceType.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
//// [differenceType.ts]
|
||||
type A = 'a';
|
||||
type B = 'b';
|
||||
type C = 'c';
|
||||
type AB = A | B;
|
||||
let nothing: A - 'a';
|
||||
let none: AB - 'a' | 'b';
|
||||
let over: 'a' - 'a' | 'b';
|
||||
let under: 'a' | 'b' - 'a';
|
||||
let partial: 'a' | 'b' - 'b' | 'd';
|
||||
let empty: AB - AB;
|
||||
let nope: string - string;
|
||||
let nope2: 'a' | 'b' - string;
|
||||
let nope3: string - 'a' | 'b';
|
||||
|
||||
type Abcd = { a; b; c; d }
|
||||
|
||||
function f<T,U extends keyof Abcd> (t: T, u: U) {
|
||||
let usubtkey: U - keyof T;
|
||||
let usubukey: U - keyof U;
|
||||
usubtkey = usubtkey;
|
||||
|
||||
let tsubu: T - U;
|
||||
return tsubu;
|
||||
}
|
||||
|
||||
const x = f<'a' | 'b', 'b' | 'd'>('a', 'b');
|
||||
|
||||
|
||||
//// [differenceType.js]
|
||||
var nothing;
|
||||
var none;
|
||||
var over;
|
||||
var under;
|
||||
var partial;
|
||||
var empty;
|
||||
var nope;
|
||||
var nope2;
|
||||
var nope3;
|
||||
function f(t, u) {
|
||||
var usubtkey;
|
||||
var usubukey;
|
||||
usubtkey = usubtkey;
|
||||
var tsubu;
|
||||
return tsubu;
|
||||
}
|
||||
var x = f('a', 'b');
|
90
tests/baselines/reference/differenceType.symbols
Normal file
90
tests/baselines/reference/differenceType.symbols
Normal file
|
@ -0,0 +1,90 @@
|
|||
=== tests/cases/conformance/types/rest/differenceType.ts ===
|
||||
type A = 'a';
|
||||
>A : Symbol(A, Decl(differenceType.ts, 0, 0))
|
||||
|
||||
type B = 'b';
|
||||
>B : Symbol(B, Decl(differenceType.ts, 0, 13))
|
||||
|
||||
type C = 'c';
|
||||
>C : Symbol(C, Decl(differenceType.ts, 1, 13))
|
||||
|
||||
type AB = A | B;
|
||||
>AB : Symbol(AB, Decl(differenceType.ts, 2, 13))
|
||||
>A : Symbol(A, Decl(differenceType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(differenceType.ts, 0, 13))
|
||||
|
||||
let nothing: A - 'a';
|
||||
>nothing : Symbol(nothing, Decl(differenceType.ts, 4, 3))
|
||||
>A : Symbol(A, Decl(differenceType.ts, 0, 0))
|
||||
|
||||
let none: AB - 'a' | 'b';
|
||||
>none : Symbol(none, Decl(differenceType.ts, 5, 3))
|
||||
>AB : Symbol(AB, Decl(differenceType.ts, 2, 13))
|
||||
|
||||
let over: 'a' - 'a' | 'b';
|
||||
>over : Symbol(over, Decl(differenceType.ts, 6, 3))
|
||||
|
||||
let under: 'a' | 'b' - 'a';
|
||||
>under : Symbol(under, Decl(differenceType.ts, 7, 3))
|
||||
|
||||
let partial: 'a' | 'b' - 'b' | 'd';
|
||||
>partial : Symbol(partial, Decl(differenceType.ts, 8, 3))
|
||||
|
||||
let empty: AB - AB;
|
||||
>empty : Symbol(empty, Decl(differenceType.ts, 9, 3))
|
||||
>AB : Symbol(AB, Decl(differenceType.ts, 2, 13))
|
||||
>AB : Symbol(AB, Decl(differenceType.ts, 2, 13))
|
||||
|
||||
let nope: string - string;
|
||||
>nope : Symbol(nope, Decl(differenceType.ts, 10, 3))
|
||||
|
||||
let nope2: 'a' | 'b' - string;
|
||||
>nope2 : Symbol(nope2, Decl(differenceType.ts, 11, 3))
|
||||
|
||||
let nope3: string - 'a' | 'b';
|
||||
>nope3 : Symbol(nope3, Decl(differenceType.ts, 12, 3))
|
||||
|
||||
type Abcd = { a; b; c; d }
|
||||
>Abcd : Symbol(Abcd, Decl(differenceType.ts, 12, 30))
|
||||
>a : Symbol(a, Decl(differenceType.ts, 14, 13))
|
||||
>b : Symbol(b, Decl(differenceType.ts, 14, 16))
|
||||
>c : Symbol(c, Decl(differenceType.ts, 14, 19))
|
||||
>d : Symbol(d, Decl(differenceType.ts, 14, 22))
|
||||
|
||||
function f<T,U extends keyof Abcd> (t: T, u: U) {
|
||||
>f : Symbol(f, Decl(differenceType.ts, 14, 26))
|
||||
>T : Symbol(T, Decl(differenceType.ts, 16, 11))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
>Abcd : Symbol(Abcd, Decl(differenceType.ts, 12, 30))
|
||||
>t : Symbol(t, Decl(differenceType.ts, 16, 36))
|
||||
>T : Symbol(T, Decl(differenceType.ts, 16, 11))
|
||||
>u : Symbol(u, Decl(differenceType.ts, 16, 41))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
|
||||
let usubtkey: U - keyof T;
|
||||
>usubtkey : Symbol(usubtkey, Decl(differenceType.ts, 17, 7))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
>T : Symbol(T, Decl(differenceType.ts, 16, 11))
|
||||
|
||||
let usubukey: U - keyof U;
|
||||
>usubukey : Symbol(usubukey, Decl(differenceType.ts, 18, 7))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
|
||||
usubtkey = usubtkey;
|
||||
>usubtkey : Symbol(usubtkey, Decl(differenceType.ts, 17, 7))
|
||||
>usubtkey : Symbol(usubtkey, Decl(differenceType.ts, 17, 7))
|
||||
|
||||
let tsubu: T - U;
|
||||
>tsubu : Symbol(tsubu, Decl(differenceType.ts, 21, 7))
|
||||
>T : Symbol(T, Decl(differenceType.ts, 16, 11))
|
||||
>U : Symbol(U, Decl(differenceType.ts, 16, 13))
|
||||
|
||||
return tsubu;
|
||||
>tsubu : Symbol(tsubu, Decl(differenceType.ts, 21, 7))
|
||||
}
|
||||
|
||||
const x = f<'a' | 'b', 'b' | 'd'>('a', 'b');
|
||||
>x : Symbol(x, Decl(differenceType.ts, 25, 5))
|
||||
>f : Symbol(f, Decl(differenceType.ts, 14, 26))
|
||||
|
94
tests/baselines/reference/differenceType.types
Normal file
94
tests/baselines/reference/differenceType.types
Normal file
|
@ -0,0 +1,94 @@
|
|||
=== tests/cases/conformance/types/rest/differenceType.ts ===
|
||||
type A = 'a';
|
||||
>A : "a"
|
||||
|
||||
type B = 'b';
|
||||
>B : "b"
|
||||
|
||||
type C = 'c';
|
||||
>C : "c"
|
||||
|
||||
type AB = A | B;
|
||||
>AB : "a" | "b"
|
||||
>A : "a"
|
||||
>B : "b"
|
||||
|
||||
let nothing: A - 'a';
|
||||
>nothing : never
|
||||
>A : "a"
|
||||
|
||||
let none: AB - 'a' | 'b';
|
||||
>none : never
|
||||
>AB : "a" | "b"
|
||||
|
||||
let over: 'a' - 'a' | 'b';
|
||||
>over : never
|
||||
|
||||
let under: 'a' | 'b' - 'a';
|
||||
>under : "b"
|
||||
|
||||
let partial: 'a' | 'b' - 'b' | 'd';
|
||||
>partial : "a"
|
||||
|
||||
let empty: AB - AB;
|
||||
>empty : never
|
||||
>AB : "a" | "b"
|
||||
>AB : "a" | "b"
|
||||
|
||||
let nope: string - string;
|
||||
>nope : never
|
||||
|
||||
let nope2: 'a' | 'b' - string;
|
||||
>nope2 : never
|
||||
|
||||
let nope3: string - 'a' | 'b';
|
||||
>nope3 : string
|
||||
|
||||
type Abcd = { a; b; c; d }
|
||||
>Abcd : Abcd
|
||||
>a : any
|
||||
>b : any
|
||||
>c : any
|
||||
>d : any
|
||||
|
||||
function f<T,U extends keyof Abcd> (t: T, u: U) {
|
||||
>f : <T, U extends "a" | "b" | "d" | "c">(t: T, u: U) => T - U
|
||||
>T : T
|
||||
>U : U
|
||||
>Abcd : Abcd
|
||||
>t : T
|
||||
>T : T
|
||||
>u : U
|
||||
>U : U
|
||||
|
||||
let usubtkey: U - keyof T;
|
||||
>usubtkey : U - keyof T
|
||||
>U : U
|
||||
>T : T
|
||||
|
||||
let usubukey: U - keyof U;
|
||||
>usubukey : U - keyof U
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
usubtkey = usubtkey;
|
||||
>usubtkey = usubtkey : U - keyof T
|
||||
>usubtkey : U - keyof T
|
||||
>usubtkey : U - keyof T
|
||||
|
||||
let tsubu: T - U;
|
||||
>tsubu : T - U
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
return tsubu;
|
||||
>tsubu : T - U
|
||||
}
|
||||
|
||||
const x = f<'a' | 'b', 'b' | 'd'>('a', 'b');
|
||||
>x : "a"
|
||||
>f<'a' | 'b', 'b' | 'd'>('a', 'b') : "a"
|
||||
>f : <T, U extends "a" | "b" | "d" | "c">(t: T, u: U) => T - U
|
||||
>'a' : "a"
|
||||
>'b' : "b"
|
||||
|
125
tests/baselines/reference/differenceTypeAssignability.errors.txt
Normal file
125
tests/baselines/reference/differenceTypeAssignability.errors.txt
Normal file
|
@ -0,0 +1,125 @@
|
|||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(14,5): error TS2322: Type 'T - V' is not assignable to type 'T - U'.
|
||||
Type 'V' is not assignable to type 'U'.
|
||||
Type 'string' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(15,5): error TS2322: Type 'U' is not assignable to type 'T'.
|
||||
Type '"u"' is not assignable to type 'T'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(26,5): error TS2322: Type 'T - "c"' is not assignable to type 'T - "a"'.
|
||||
Type '"c"' is not assignable to type '"a"'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(27,5): error TS2322: Type 'T - AB' is not assignable to type 'T - "a"'.
|
||||
Type 'AB' is not assignable to type '"a"'.
|
||||
Type '"b"' is not assignable to type '"a"'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(28,5): error TS2322: Type 'T - "a"' is not assignable to type 'T'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(29,5): error TS2322: Type 'U' is not assignable to type 'T'.
|
||||
Type '"u"' is not assignable to type 'T'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(38,5): error TS2322: Type '{ a: any; }' is not assignable to type '{ a: any; b: any; }'.
|
||||
Property 'b' is missing in type '{ a: any; }'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(39,5): error TS2322: Type '{ a: any; b: any; } - T' is not assignable to type '{ a: any; b: any; } - U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type '"x" | "y" | "z"' is not assignable to type 'U'.
|
||||
Type '"x"' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(40,5): error TS2322: Type '{ a: any; c: any; }' is not assignable to type '{ a: any; b: any; }'.
|
||||
Property 'b' is missing in type '{ a: any; c: any; }'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(42,5): error TS2322: Type '{ a: any; }' is not assignable to type 'T'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(43,5): error TS2322: Type 'T - U' is not assignable to type 'T - "a"'.
|
||||
Type 'U' is not assignable to type '"a"'.
|
||||
Type '"u"' is not assignable to type '"a"'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(44,5): error TS2322: Type 'T - "a"' is not assignable to type 'T - U'.
|
||||
Type '"a"' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(47,5): error TS2322: Type 'BN' is not assignable to type 'T - "a"'.
|
||||
tests/cases/conformance/types/rest/differenceTypeAssignability.ts(48,5): error TS2322: Type 'T - "a"' is not assignable to type 'BN'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/differenceTypeAssignability.ts (14 errors) ====
|
||||
type A = 'a';
|
||||
type B = 'b';
|
||||
type C = 'c';
|
||||
type AB = A | B;
|
||||
type AC = A | C;
|
||||
type BN = { b: number };
|
||||
function f<T extends 'x' | 'y' | 'z', U extends 'u', V extends string> (t: T, u: U, v: V) {
|
||||
let t_u: T - U;
|
||||
let t_v: T - V;
|
||||
let u_t: U - T;
|
||||
|
||||
t_u = t; // ok
|
||||
t_u = t_u; // ok
|
||||
t_u = t_v; // error
|
||||
~~~
|
||||
!!! error TS2322: Type 'T - V' is not assignable to type 'T - U'.
|
||||
!!! error TS2322: Type 'V' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'U'.
|
||||
t_u = u_t; // error
|
||||
~~~
|
||||
!!! error TS2322: Type 'U' is not assignable to type 'T'.
|
||||
!!! error TS2322: Type '"u"' is not assignable to type 'T'.
|
||||
|
||||
var t_a: T - A;
|
||||
var t_c: T - C;
|
||||
var t_ab: T - AB;
|
||||
var u_a: U - A;
|
||||
|
||||
t_a = t_a; // ok
|
||||
t_ab = t_a; // ok
|
||||
t_a = t; // ok
|
||||
|
||||
t_a = t_c; // error
|
||||
~~~
|
||||
!!! error TS2322: Type 'T - "c"' is not assignable to type 'T - "a"'.
|
||||
!!! error TS2322: Type '"c"' is not assignable to type '"a"'.
|
||||
t_a = t_ab; // error
|
||||
~~~
|
||||
!!! error TS2322: Type 'T - AB' is not assignable to type 'T - "a"'.
|
||||
!!! error TS2322: Type 'AB' is not assignable to type '"a"'.
|
||||
!!! error TS2322: Type '"b"' is not assignable to type '"a"'.
|
||||
t = t_a; // error, T-a is missing 'a' if T contains 'a'
|
||||
~
|
||||
!!! error TS2322: Type 'T - "a"' is not assignable to type 'T'.
|
||||
t_a = u_a; // error
|
||||
~~~
|
||||
!!! error TS2322: Type 'U' is not assignable to type 'T'.
|
||||
!!! error TS2322: Type '"u"' is not assignable to type 'T'.
|
||||
|
||||
var ab_u: { a, b } - U;
|
||||
var ab_t: { a, b } - T;
|
||||
var a_t: { a } - T;
|
||||
var ac_t: { a, c } - T;
|
||||
|
||||
ab_t = ab_t; // ok
|
||||
a_t = ab_t; // ok
|
||||
ab_t = a_t; // error
|
||||
~~~~
|
||||
!!! error TS2322: Type '{ a: any; }' is not assignable to type '{ a: any; b: any; }'.
|
||||
!!! error TS2322: Property 'b' is missing in type '{ a: any; }'.
|
||||
ab_u = ab_t; // error
|
||||
~~~~
|
||||
!!! error TS2322: Type '{ a: any; b: any; } - T' is not assignable to type '{ a: any; b: any; } - U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type '"x" | "y" | "z"' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type '"x"' is not assignable to type 'U'.
|
||||
ab_t = ac_t // error
|
||||
~~~~
|
||||
!!! error TS2322: Type '{ a: any; c: any; }' is not assignable to type '{ a: any; b: any; }'.
|
||||
!!! error TS2322: Property 'b' is missing in type '{ a: any; c: any; }'.
|
||||
|
||||
t_a = a_t; // error, this makes no sense.
|
||||
~~~
|
||||
!!! error TS2322: Type '{ a: any; }' is not assignable to type 'T'.
|
||||
t_a = t_u; // error, let T and U contain property u. Then T-a has property u but T-U does not.
|
||||
~~~
|
||||
!!! error TS2322: Type 'T - U' is not assignable to type 'T - "a"'.
|
||||
!!! error TS2322: Type 'U' is not assignable to type '"a"'.
|
||||
!!! error TS2322: Type '"u"' is not assignable to type '"a"'.
|
||||
t_u = t_a; // error, let T contain property a and U not. Then T-a has no a, but T-U does.
|
||||
~~~
|
||||
!!! error TS2322: Type 'T - "a"' is not assignable to type 'T - U'.
|
||||
!!! error TS2322: Type '"a"' is not assignable to type 'U'.
|
||||
|
||||
var bn: BN;
|
||||
t_a = bn; // error, we have no idea what T is supposed to be
|
||||
~~~
|
||||
!!! error TS2322: Type 'BN' is not assignable to type 'T - "a"'.
|
||||
bn = t_a; // would be ok only if T extends BN
|
||||
~~
|
||||
!!! error TS2322: Type 'T - "a"' is not assignable to type 'BN'.
|
||||
}
|
||||
|
88
tests/baselines/reference/differenceTypeAssignability.js
Normal file
88
tests/baselines/reference/differenceTypeAssignability.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
//// [differenceTypeAssignability.ts]
|
||||
type A = 'a';
|
||||
type B = 'b';
|
||||
type C = 'c';
|
||||
type AB = A | B;
|
||||
type AC = A | C;
|
||||
type BN = { b: number };
|
||||
function f<T extends 'x' | 'y' | 'z', U extends 'u', V extends string> (t: T, u: U, v: V) {
|
||||
let t_u: T - U;
|
||||
let t_v: T - V;
|
||||
let u_t: U - T;
|
||||
|
||||
t_u = t; // ok
|
||||
t_u = t_u; // ok
|
||||
t_u = t_v; // error
|
||||
t_u = u_t; // error
|
||||
|
||||
var t_a: T - A;
|
||||
var t_c: T - C;
|
||||
var t_ab: T - AB;
|
||||
var u_a: U - A;
|
||||
|
||||
t_a = t_a; // ok
|
||||
t_ab = t_a; // ok
|
||||
t_a = t; // ok
|
||||
|
||||
t_a = t_c; // error
|
||||
t_a = t_ab; // error
|
||||
t = t_a; // error, T-a is missing 'a' if T contains 'a'
|
||||
t_a = u_a; // error
|
||||
|
||||
var ab_u: { a, b } - U;
|
||||
var ab_t: { a, b } - T;
|
||||
var a_t: { a } - T;
|
||||
var ac_t: { a, c } - T;
|
||||
|
||||
ab_t = ab_t; // ok
|
||||
a_t = ab_t; // ok
|
||||
ab_t = a_t; // error
|
||||
ab_u = ab_t; // error
|
||||
ab_t = ac_t // error
|
||||
|
||||
t_a = a_t; // error, this makes no sense.
|
||||
t_a = t_u; // error, let T and U contain property u. Then T-a has property u but T-U does not.
|
||||
t_u = t_a; // error, let T contain property a and U not. Then T-a has no a, but T-U does.
|
||||
|
||||
var bn: BN;
|
||||
t_a = bn; // error, we have no idea what T is supposed to be
|
||||
bn = t_a; // would be ok only if T extends BN
|
||||
}
|
||||
|
||||
|
||||
//// [differenceTypeAssignability.js]
|
||||
function f(t, u, v) {
|
||||
var t_u;
|
||||
var t_v;
|
||||
var u_t;
|
||||
t_u = t; // ok
|
||||
t_u = t_u; // ok
|
||||
t_u = t_v; // error
|
||||
t_u = u_t; // error
|
||||
var t_a;
|
||||
var t_c;
|
||||
var t_ab;
|
||||
var u_a;
|
||||
t_a = t_a; // ok
|
||||
t_ab = t_a; // ok
|
||||
t_a = t; // ok
|
||||
t_a = t_c; // error
|
||||
t_a = t_ab; // error
|
||||
t = t_a; // error, T-a is missing 'a' if T contains 'a'
|
||||
t_a = u_a; // error
|
||||
var ab_u;
|
||||
var ab_t;
|
||||
var a_t;
|
||||
var ac_t;
|
||||
ab_t = ab_t; // ok
|
||||
a_t = ab_t; // ok
|
||||
ab_t = a_t; // error
|
||||
ab_u = ab_t; // error
|
||||
ab_t = ac_t; // error
|
||||
t_a = a_t; // error, this makes no sense.
|
||||
t_a = t_u; // error, let T and U contain property u. Then T-a has property u but T-U does not.
|
||||
t_u = t_a; // error, let T contain property a and U not. Then T-a has no a, but T-U does.
|
||||
var bn;
|
||||
t_a = bn; // error, we have no idea what T is supposed to be
|
||||
bn = t_a; // would be ok only if T extends BN
|
||||
}
|
65
tests/baselines/reference/differenceTypeNegative.errors.txt
Normal file
65
tests/baselines/reference/differenceTypeNegative.errors.txt
Normal file
|
@ -0,0 +1,65 @@
|
|||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(3,17): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(4,17): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(5,17): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(6,17): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(8,21): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(9,21): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(10,21): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(11,21): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(12,21): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(18,5): error TS2322: Type 'U - keyof T' is not assignable to type 'U - keyof U'.
|
||||
Type 'keyof T' is not assignable to type 'keyof U'.
|
||||
Type 'keyof T' is not assignable to type '"toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
|
||||
Type 'keyof T' is not assignable to type '"valueOf"'.
|
||||
tests/cases/conformance/types/rest/differenceTypeNegative.ts(19,5): error TS2322: Type 'U - keyof U' is not assignable to type 'U - keyof T'.
|
||||
Type 'keyof U' is not assignable to type 'keyof T'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/differenceTypeNegative.ts (11 errors) ====
|
||||
type Abc = { a; b; c }
|
||||
type Surprise = 'a' | 'b' | 12;
|
||||
let bad1: Abc - 12;
|
||||
~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad2: Abc - Surprise;
|
||||
~~~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad3: Abc - 'a' & 'b';
|
||||
~~~~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad4: Abc - number;
|
||||
~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
function f<T, U extends 12, V extends Surprise, W extends 'a' & 'b', X extends number>(t: T) {
|
||||
let bad1: Abc - T;
|
||||
~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad2: Abc - 12;
|
||||
~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad3: Abc - Surprise;
|
||||
~~~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad4: Abc - 'a' & 'b';
|
||||
~~~~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
let bad5: Abc - number;
|
||||
~~~~~~
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
return bad1;
|
||||
}
|
||||
function g<T,U extends keyof Abc> (t: T, u: U) {
|
||||
let usubtkey: U - keyof T;
|
||||
let usubukey: U - keyof U;
|
||||
usubukey = usubtkey;
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'U - keyof T' is not assignable to type 'U - keyof U'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type '"toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type '"valueOf"'.
|
||||
usubtkey = usubukey;
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'U - keyof U' is not assignable to type 'U - keyof T'.
|
||||
!!! error TS2322: Type 'keyof U' is not assignable to type 'keyof T'.
|
||||
}
|
||||
|
42
tests/baselines/reference/differenceTypeNegative.js
Normal file
42
tests/baselines/reference/differenceTypeNegative.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
//// [differenceTypeNegative.ts]
|
||||
type Abc = { a; b; c }
|
||||
type Surprise = 'a' | 'b' | 12;
|
||||
let bad1: Abc - 12;
|
||||
let bad2: Abc - Surprise;
|
||||
let bad3: Abc - 'a' & 'b';
|
||||
let bad4: Abc - number;
|
||||
function f<T, U extends 12, V extends Surprise, W extends 'a' & 'b', X extends number>(t: T) {
|
||||
let bad1: Abc - T;
|
||||
let bad2: Abc - 12;
|
||||
let bad3: Abc - Surprise;
|
||||
let bad4: Abc - 'a' & 'b';
|
||||
let bad5: Abc - number;
|
||||
return bad1;
|
||||
}
|
||||
function g<T,U extends keyof Abc> (t: T, u: U) {
|
||||
let usubtkey: U - keyof T;
|
||||
let usubukey: U - keyof U;
|
||||
usubukey = usubtkey;
|
||||
usubtkey = usubukey;
|
||||
}
|
||||
|
||||
|
||||
//// [differenceTypeNegative.js]
|
||||
var bad1;
|
||||
var bad2;
|
||||
var bad3;
|
||||
var bad4;
|
||||
function f(t) {
|
||||
var bad1;
|
||||
var bad2;
|
||||
var bad3;
|
||||
var bad4;
|
||||
var bad5;
|
||||
return bad1;
|
||||
}
|
||||
function g(t, u) {
|
||||
var usubtkey;
|
||||
var usubukey;
|
||||
usubukey = usubtkey;
|
||||
usubtkey = usubukey;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
tests/cases/compiler/dontShowCompilerGeneratedMembers.ts(1,5): error TS2322: Type 'number' is not assignable to type '{ (): any; x: number; }'.
|
||||
tests/cases/compiler/dontShowCompilerGeneratedMembers.ts(3,6): error TS1139: Type parameter declaration expected.
|
||||
tests/cases/compiler/dontShowCompilerGeneratedMembers.ts(4,1): error TS1109: Expression expected.
|
||||
tests/cases/compiler/dontShowCompilerGeneratedMembers.ts(3,7): error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
tests/cases/compiler/dontShowCompilerGeneratedMembers.ts(4,1): error TS1110: Type expected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/dontShowCompilerGeneratedMembers.ts (3 errors) ====
|
||||
var f: {
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type '{ (): any; x: number; }'.
|
||||
x: number;
|
||||
<-
|
||||
~
|
||||
!!! error TS1139: Type parameter declaration expected.
|
||||
|
||||
!!! error TS2705: The right side of a difference type must be a string or string literal union, or a type parameter constrained to one of these.
|
||||
};
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
!!! error TS1110: Type expected.
|
|
@ -5,5 +5,5 @@ var f: {
|
|||
};
|
||||
|
||||
//// [dontShowCompilerGeneratedMembers.js]
|
||||
var f = -;
|
||||
var f;
|
||||
;
|
||||
|
|
26
tests/cases/conformance/types/rest/differenceType.ts
Normal file
26
tests/cases/conformance/types/rest/differenceType.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
type A = 'a';
|
||||
type B = 'b';
|
||||
type C = 'c';
|
||||
type AB = A | B;
|
||||
let nothing: A - 'a';
|
||||
let none: AB - 'a' | 'b';
|
||||
let over: 'a' - 'a' | 'b';
|
||||
let under: 'a' | 'b' - 'a';
|
||||
let partial: 'a' | 'b' - 'b' | 'd';
|
||||
let empty: AB - AB;
|
||||
let nope: string - string;
|
||||
let nope2: 'a' | 'b' - string;
|
||||
let nope3: string - 'a' | 'b';
|
||||
|
||||
type Abcd = { a; b; c; d }
|
||||
|
||||
function f<T,U extends keyof Abcd> (t: T, u: U) {
|
||||
let usubtkey: U - keyof T;
|
||||
let usubukey: U - keyof U;
|
||||
usubtkey = usubtkey;
|
||||
|
||||
let tsubu: T - U;
|
||||
return tsubu;
|
||||
}
|
||||
|
||||
const x = f<'a' | 'b', 'b' | 'd'>('a', 'b');
|
|
@ -0,0 +1,49 @@
|
|||
type A = 'a';
|
||||
type B = 'b';
|
||||
type C = 'c';
|
||||
type AB = A | B;
|
||||
type AC = A | C;
|
||||
type BN = { b: number };
|
||||
function f<T extends 'x' | 'y' | 'z', U extends 'u', V extends string> (t: T, u: U, v: V) {
|
||||
let t_u: T - U;
|
||||
let t_v: T - V;
|
||||
let u_t: U - T;
|
||||
|
||||
t_u = t; // ok
|
||||
t_u = t_u; // ok
|
||||
t_u = t_v; // error
|
||||
t_u = u_t; // error
|
||||
|
||||
var t_a: T - A;
|
||||
var t_c: T - C;
|
||||
var t_ab: T - AB;
|
||||
var u_a: U - A;
|
||||
|
||||
t_a = t_a; // ok
|
||||
t_ab = t_a; // ok
|
||||
t_a = t; // ok
|
||||
|
||||
t_a = t_c; // error
|
||||
t_a = t_ab; // error
|
||||
t = t_a; // error, T-a is missing 'a' if T contains 'a'
|
||||
t_a = u_a; // error
|
||||
|
||||
var ab_u: { a, b } - U;
|
||||
var ab_t: { a, b } - T;
|
||||
var a_t: { a } - T;
|
||||
var ac_t: { a, c } - T;
|
||||
|
||||
ab_t = ab_t; // ok
|
||||
a_t = ab_t; // ok
|
||||
ab_t = a_t; // error
|
||||
ab_u = ab_t; // error
|
||||
ab_t = ac_t // error
|
||||
|
||||
t_a = a_t; // error, this makes no sense.
|
||||
t_a = t_u; // error, let T and U contain property u. Then T-a has property u but T-U does not.
|
||||
t_u = t_a; // error, let T contain property a and U not. Then T-a has no a, but T-U does.
|
||||
|
||||
var bn: BN;
|
||||
t_a = bn; // error, we have no idea what T is supposed to be
|
||||
bn = t_a; // would be ok only if T extends BN
|
||||
}
|
20
tests/cases/conformance/types/rest/differenceTypeNegative.ts
Normal file
20
tests/cases/conformance/types/rest/differenceTypeNegative.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
type Abc = { a; b; c }
|
||||
type Surprise = 'a' | 'b' | 12;
|
||||
let bad1: Abc - 12;
|
||||
let bad2: Abc - Surprise;
|
||||
let bad3: Abc - 'a' & 'b';
|
||||
let bad4: Abc - number;
|
||||
function f<T, U extends 12, V extends Surprise, W extends 'a' & 'b', X extends number>(t: T) {
|
||||
let bad1: Abc - T;
|
||||
let bad2: Abc - 12;
|
||||
let bad3: Abc - Surprise;
|
||||
let bad4: Abc - 'a' & 'b';
|
||||
let bad5: Abc - number;
|
||||
return bad1;
|
||||
}
|
||||
function g<T,U extends keyof Abc> (t: T, u: U) {
|
||||
let usubtkey: U - keyof T;
|
||||
let usubukey: U - keyof U;
|
||||
usubukey = usubtkey;
|
||||
usubtkey = usubukey;
|
||||
}
|
Loading…
Reference in a new issue