Experimenting with new type operators

This commit is contained in:
Ron Buckton 2017-12-05 10:58:30 -08:00
parent 3ea031cf1c
commit 86b687dd58
24 changed files with 1658 additions and 780 deletions

View File

@ -3364,10 +3364,13 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.ThisType:
case SyntaxKind.TypeOperator:
case SyntaxKind.UnaryType:
case SyntaxKind.BinaryType:
case SyntaxKind.ConditionalType:
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.LiteralType:
case SyntaxKind.CallType:
case SyntaxKind.NamespaceExportDeclaration:
// Types and signatures are TypeScript syntax, and exclude all other facts.
transformFlags = TransformFlags.AssertTypeScript;

File diff suppressed because it is too large Load Diff

View File

@ -441,12 +441,18 @@ namespace ts {
return emitIntersectionType(<IntersectionTypeNode>type);
case SyntaxKind.ParenthesizedType:
return emitParenType(<ParenthesizedTypeNode>type);
case SyntaxKind.TypeOperator:
return emitTypeOperator(<TypeOperatorNode>type);
case SyntaxKind.UnaryType:
return emitUnaryType(<UnaryTypeNode>type);
case SyntaxKind.BinaryType:
return emitBinaryType(<BinaryTypeNode>type);
case SyntaxKind.ConditionalType:
return emitConditionalType(<ConditionalTypeNode>type);
case SyntaxKind.IndexedAccessType:
return emitIndexedAccessType(<IndexedAccessTypeNode>type);
case SyntaxKind.MappedType:
return emitMappedType(<MappedTypeNode>type);
case SyntaxKind.CallType:
return emitCallType(<CallTypeNode>type);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return emitSignatureDeclarationWithJsDocComments(<FunctionOrConstructorTypeNode>type);
@ -540,12 +546,28 @@ namespace ts {
write(")");
}
function emitTypeOperator(type: TypeOperatorNode) {
function emitUnaryType(type: UnaryTypeNode) {
write(tokenToString(type.operator));
write(" ");
emitType(type.type);
}
function emitBinaryType(type: BinaryTypeNode) {
emitType(type.left);
write(" ");
write(tokenToString(type.operator));
write(" ");
emitType(type.right);
}
function emitConditionalType(type: ConditionalTypeNode) {
emitType(type.condition);
write(" ? ");
emitType(type.whenTrue);
write(" : ");
emitType(type.whenFalse);
}
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
emitType(node.objectType);
write("[");
@ -579,6 +601,13 @@ namespace ts {
enclosingDeclaration = prevEnclosingDeclaration;
}
function emitCallType(node: CallTypeNode) {
emitType(node.target);
write("(");
emitCommaList(node.arguments, emitType);
write(")");
}
function emitTypeLiteral(type: TypeLiteralNode) {
write("{");
if (type.members.length) {

View File

@ -551,12 +551,18 @@ namespace ts {
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
case SyntaxKind.ThisType:
return emitThisType();
case SyntaxKind.TypeOperator:
return emitTypeOperator(<TypeOperatorNode>node);
case SyntaxKind.UnaryType:
return emitUnaryType(<UnaryTypeNode>node);
case SyntaxKind.BinaryType:
return emitBinaryType(<BinaryTypeNode>node);
case SyntaxKind.ConditionalType:
return emitConditionalType(<ConditionalTypeNode>node);
case SyntaxKind.IndexedAccessType:
return emitIndexedAccessType(<IndexedAccessTypeNode>node);
case SyntaxKind.MappedType:
return emitMappedType(<MappedTypeNode>node);
case SyntaxKind.CallType:
return emitCallType(<CallTypeNode>node);
case SyntaxKind.LiteralType:
return emitLiteralType(<LiteralTypeNode>node);
@ -1071,12 +1077,28 @@ namespace ts {
write("this");
}
function emitTypeOperator(node: TypeOperatorNode) {
function emitUnaryType(node: UnaryTypeNode) {
writeTokenText(node.operator);
write(" ");
emit(node.type);
}
function emitBinaryType(node: BinaryTypeNode) {
emit(node.left);
write(" ");
writeTokenText(node.operator);
write(" ");
emit(node.right);
}
function emitConditionalType(node: ConditionalTypeNode) {
emit(node.condition);
write(" ? ");
emit(node.whenTrue);
write(" : ");
emit(node.whenFalse);
}
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
emit(node.objectType);
write("[");
@ -1114,6 +1136,13 @@ namespace ts {
write("}");
}
function emitCallType(node: CallTypeNode) {
emit(node.target);
write("(");
emitList(node, node.arguments, ListFormat.Parameters);
write(")");
}
function emitLiteralType(node: LiteralTypeNode) {
emitExpression(node.literal);
}

View File

@ -611,7 +611,7 @@ namespace ts {
export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray<TypeNode> | undefined) {
const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode;
node.typeName = asName(typeName);
node.typeArguments = typeArguments && parenthesizeTypeParameters(typeArguments);
node.typeArguments = asNodeArray(sameMap(typeArguments, parenthesizeTypeArgument));
return node;
}
@ -664,7 +664,7 @@ namespace ts {
export function createArrayTypeNode(elementType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode;
node.elementType = parenthesizeArrayTypeMember(elementType);
node.elementType = parenthesizeTypeNode(elementType, SyntaxKind.ArrayType);
return node;
}
@ -704,7 +704,7 @@ namespace ts {
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: ReadonlyArray<TypeNode>) {
const node = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode;
node.types = parenthesizeElementTypeMembers(types);
node.types = createNodeArray(sameMap(types, kind === SyntaxKind.UnionType ? parenthesizeUnionTypeConstituent : parenthesizeIntersectionTypeConstituent));
return node;
}
@ -730,20 +730,24 @@ namespace ts {
return <ThisTypeNode>createSynthesizedNode(SyntaxKind.ThisType);
}
export function createTypeOperatorNode(type: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
node.operator = SyntaxKind.KeyOfKeyword;
node.type = parenthesizeElementTypeMember(type);
export function createUnaryTypeNode(operator: UnaryTypeOperator, type: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.UnaryType) as UnaryTypeNode;
node.operator = operator;
node.type = parenthesizeTypeNode(type, SyntaxKind.UnaryType, operator);
return node;
}
export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) {
return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node;
export function createTypeOperatorNode(type: TypeNode) {
return createUnaryTypeNode(SyntaxKind.KeyOfKeyword, type); // backwards compatibility
}
export function updateTypeOperatorNode(node: UnaryTypeNode, type: TypeNode) {
return node.type !== type ? updateNode(createUnaryTypeNode(node.operator, type), node) : node;
}
export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode;
node.objectType = parenthesizeElementTypeMember(objectType);
node.objectType = parenthesizeTypeNode(objectType, SyntaxKind.IndexedAccessType);
node.indexType = indexType;
return node;
}
@ -755,6 +759,44 @@ namespace ts {
: node;
}
export function createBinaryTypeNode(left: TypeNode, operator: BinaryTypeOperator, right: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.BinaryType) as BinaryTypeNode;
node.left = parenthesizeTypeNode(left, SyntaxKind.BinaryType, operator);
node.operator = operator;
node.right = parenthesizeTypeNode(right, SyntaxKind.BinaryType, operator);
return node;
}
export function updateBinaryTypeNode(node: BinaryTypeNode, left: TypeNode, right: TypeNode) {
return node.left !== left
|| node.right !== right
? updateNode(createBinaryTypeNode(left, node.operator, right), node)
: node;
}
export function createConditionalTypeNode(condition: TypeNode, whenTrue: TypeNode, whenFalse: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.ConditionalType) as ConditionalTypeNode;
node.condition = parenthesizeTypeNode(condition, SyntaxKind.ConditionalType, SyntaxKind.QuestionToken);
node.whenTrue = whenTrue;
node.whenFalse = whenFalse;
return node;
}
export function updateConditionalTypeNode(node: ConditionalTypeNode, condition: TypeNode, whenTrue: TypeNode, whenFalse: TypeNode) {
return node.condition !== condition
|| node.whenTrue !== whenTrue
|| node.whenFalse !== whenFalse
? updateNode(createConditionalTypeNode(condition, whenTrue, whenFalse), node)
: node;
}
export function createCallTypeNode(target: TypeNode, argumentList: ReadonlyArray<TypeNode>) {
const node = createSynthesizedNode(SyntaxKind.CallType) as CallTypeNode;
node.target = parenthesizeTypeNode(target, SyntaxKind.CallType);
node.arguments = createNodeArray(argumentList);
return node;
}
export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode {
const node = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode;
node.readonlyToken = readonlyToken;
@ -773,6 +815,20 @@ namespace ts {
: node;
}
export function createCallType(target: TypeNode, argumentList: ReadonlyArray<TypeNode>) {
const node = createSynthesizedNode(SyntaxKind.CallType) as CallTypeNode;
node.target = parenthesizeTypeNode(target, SyntaxKind.CallType);
node.arguments = createNodeArray(argumentList);
return node;
}
export function updateCallType(node: CallTypeNode, target: TypeNode, argumentList: ReadonlyArray<TypeNode>) {
return node.target !== target
|| node.arguments !== argumentList
? updateNode(createCallType(target, argumentList), node)
: node;
}
export function createLiteralTypeNode(literal: Expression) {
const node = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode;
node.literal = literal;
@ -2757,6 +2813,26 @@ namespace ts {
}
return destRanges;
}
function parenthesizeTypeNode(node: TypeNode, containerKind: SyntaxKind, operatorKind?: SyntaxKind) {
const operatorPrecedence = getTypeOperatorPrecedence(containerKind, operatorKind);
const nodePrecedence = getTypePrecedence(node);
return nodePrecedence < operatorPrecedence ? createParenthesizedType(node) : node;
}
function parenthesizeUnionTypeConstituent(node: TypeNode) {
return parenthesizeTypeNode(node, SyntaxKind.UnionType, SyntaxKind.BarToken);
}
function parenthesizeIntersectionTypeConstituent(node: TypeNode) {
return parenthesizeTypeNode(node, SyntaxKind.IntersectionType, SyntaxKind.AmpersandToken);
}
function parenthesizeTypeArgument(typeArgument: TypeNode, typeArgumentIndex: number) {
return typeArgumentIndex === 0 && isFunctionOrConstructorTypeNode(typeArgument) && typeArgument.typeParameters
? createParenthesizedType(typeArgument)
: typeArgument;
}
}
/* @internal */
@ -3901,44 +3977,6 @@ namespace ts {
return expression;
}
export function parenthesizeElementTypeMember(member: TypeNode) {
switch (member.kind) {
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return createParenthesizedType(member);
}
return member;
}
export function parenthesizeArrayTypeMember(member: TypeNode) {
switch (member.kind) {
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeOperator:
return createParenthesizedType(member);
}
return parenthesizeElementTypeMember(member);
}
export function parenthesizeElementTypeMembers(members: ReadonlyArray<TypeNode>) {
return createNodeArray(sameMap(members, parenthesizeElementTypeMember));
}
export function parenthesizeTypeParameters(typeParameters: ReadonlyArray<TypeNode>) {
if (some(typeParameters)) {
const params: TypeNode[] = [];
for (let i = 0; i < typeParameters.length; ++i) {
const entry = typeParameters[i];
params.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
createParenthesizedType(entry) :
entry);
}
return createNodeArray(params);
}
}
function getLeftmostExpression(node: Expression): Expression {
while (true) {
switch (node.kind) {

View File

@ -145,8 +145,15 @@ namespace ts {
case SyntaxKind.IntersectionType:
return visitNodes(cbNode, cbNodes, (<UnionOrIntersectionTypeNode>node).types);
case SyntaxKind.ParenthesizedType:
case SyntaxKind.TypeOperator:
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
case SyntaxKind.UnaryType:
return visitNode(cbNode, (<ParenthesizedTypeNode | UnaryTypeNode>node).type);
case SyntaxKind.BinaryType:
return visitNode(cbNode, (<BinaryTypeNode>node).left) ||
visitNode(cbNode, (<BinaryTypeNode>node).right);
case SyntaxKind.ConditionalType:
return visitNode(cbNode, (<ConditionalTypeNode>node).condition) ||
visitNode(cbNode, (<ConditionalTypeNode>node).whenTrue) ||
visitNode(cbNode, (<ConditionalTypeNode>node).whenFalse);
case SyntaxKind.IndexedAccessType:
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
@ -155,6 +162,9 @@ namespace ts {
visitNode(cbNode, (<MappedTypeNode>node).typeParameter) ||
visitNode(cbNode, (<MappedTypeNode>node).questionToken) ||
visitNode(cbNode, (<MappedTypeNode>node).type);
case SyntaxKind.CallType:
return visitNode(cbNode, (<CallTypeNode>node).target) ||
visitNodes(cbNode, cbNodes, (<CallTypeNode>node).arguments);
case SyntaxKind.LiteralType:
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
case SyntaxKind.ObjectBindingPattern:
@ -2757,13 +2767,12 @@ namespace ts {
case SyntaxKind.ExclamationToken:
return SyntaxKind.JSDocNonNullableType;
case SyntaxKind.QuestionToken:
return SyntaxKind.JSDocNullableType;
return contextFlags & NodeFlags.JSDoc ? SyntaxKind.JSDocNullableType : undefined;
}
}
}
function parseArrayTypeOrHigher(): TypeNode {
let type = parseJSDocPostfixTypeOrHigher();
function parseArrayOrIndexedAccessTypeRest(type: TypeNode) {
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
if (isStartOfType()) {
const node = <IndexedAccessTypeNode>createNode(SyntaxKind.IndexedAccessType, type.pos);
@ -2782,18 +2791,47 @@ namespace ts {
return type;
}
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword) {
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
function parseCallTypeRest(type: TypeNode) {
while (true) {
type = parseArrayOrIndexedAccessTypeRest(type);
if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.OpenParenToken) {
const callType = <CallTypeNode>createNode(SyntaxKind.CallType, type.pos);
callType.target = type;
callType.arguments = parseTypeArgumentsInCallType();
type = finishNode(callType);
continue;
}
return type;
}
}
function parseTypeArgumentsInCallType() {
parseExpected(SyntaxKind.OpenParenToken);
const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
parseExpected(SyntaxKind.CloseParenToken);
return typeArguments;
}
function parseArrayTypeOrHigher(): TypeNode {
let type = parseJSDocPostfixTypeOrHigher();
return parseCallTypeRest(type);
}
function parseUnaryType(operator: UnaryTypeOperator) {
const node = <UnaryTypeNode>createNode(SyntaxKind.UnaryType);
parseExpected(operator);
node.operator = operator;
node.type = parseTypeOperatorOrHigher();
node.type = parseUnaryTypeOrHigher();
return finishNode(node);
}
function parseTypeOperatorOrHigher(): TypeNode {
switch (token()) {
function parseUnaryTypeOrHigher(): TypeNode {
const operator = token();
switch (operator) {
case SyntaxKind.KeyOfKeyword:
return parseTypeOperator(SyntaxKind.KeyOfKeyword);
case SyntaxKind.NotKeyword:
return parseUnaryType(operator);
}
return parseArrayTypeOrHigher();
}
@ -2815,13 +2853,63 @@ namespace ts {
}
function parseIntersectionTypeOrHigher(): TypeNode {
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken);
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseUnaryTypeOrHigher, SyntaxKind.AmpersandToken);
}
function parseUnionTypeOrHigher(): TypeNode {
return parseUnionOrIntersectionType(SyntaxKind.UnionType, parseIntersectionTypeOrHigher, SyntaxKind.BarToken);
}
function parseBinaryTypeOrHigher(precedence: number): TypeNode {
const leftType = parseUnionTypeOrHigher();
return parseBinaryTypeRest(precedence, leftType);
}
function parseBinaryTypeRest(precedence: number, leftType: TypeNode): TypeNode {
while (true) {
const operator = token();
let newPrecedence: number;
switch (operator) {
case SyntaxKind.OrKeyword:
case SyntaxKind.AndKeyword:
case SyntaxKind.ExtendsKeyword:
newPrecedence = getTypeOperatorPrecedence(SyntaxKind.BinaryType, operator);
break;
default:
return leftType;
}
if (newPrecedence <= precedence) break;
nextToken();
leftType = makeBinaryTypeOperator(leftType, operator, parseBinaryTypeOrHigher(newPrecedence));
}
return leftType;
}
function makeBinaryTypeOperator(left: TypeNode, operator: BinaryTypeOperator, right: TypeNode) {
const node = <BinaryTypeNode>createNode(SyntaxKind.BinaryType, left.pos);
node.left = left;
node.operator = operator;
node.right = right;
return finishNode(node);
}
function parseConditionalTypeRest(leftType: TypeNode): TypeNode {
if (!parseOptional(SyntaxKind.QuestionToken)) {
return leftType;
}
const node = <ConditionalTypeNode>createNode(SyntaxKind.ConditionalType, leftType.pos);
node.condition = leftType;
node.whenTrue = parseTypeWorker();
parseExpected(SyntaxKind.ColonToken);
node.whenFalse = parseTypeWorker();
return finishNode(node);
}
function isStartOfFunctionType(): boolean {
if (token() === SyntaxKind.LessThanToken) {
return true;
@ -2911,7 +2999,7 @@ namespace ts {
if (token() === SyntaxKind.NewKeyword) {
return parseFunctionOrConstructorType(SyntaxKind.ConstructorType);
}
return parseUnionTypeOrHigher();
return parseConditionalTypeRest(parseBinaryTypeOrHigher(/*precedence*/ 0));
}
function parseTypeAnnotation(): TypeNode {

View File

@ -60,6 +60,7 @@ namespace ts {
const textToToken = createMapFromTemplate({
"abstract": SyntaxKind.AbstractKeyword,
"and": SyntaxKind.AndKeyword,
"any": SyntaxKind.AnyKeyword,
"as": SyntaxKind.AsKeyword,
"boolean": SyntaxKind.BooleanKeyword,
@ -98,9 +99,11 @@ namespace ts {
"namespace": SyntaxKind.NamespaceKeyword,
"never": SyntaxKind.NeverKeyword,
"new": SyntaxKind.NewKeyword,
"not": SyntaxKind.NotKeyword,
"null": SyntaxKind.NullKeyword,
"number": SyntaxKind.NumberKeyword,
"object": SyntaxKind.ObjectKeyword,
"or": SyntaxKind.OrKeyword,
"package": SyntaxKind.PackageKeyword,
"private": SyntaxKind.PrivateKeyword,
"protected": SyntaxKind.ProtectedKeyword,

View File

@ -178,6 +178,7 @@ namespace ts {
// Contextual keywords
AbstractKeyword,
AsKeyword,
AndKeyword,
AnyKeyword,
AsyncKeyword,
AwaitKeyword,
@ -192,8 +193,10 @@ namespace ts {
NeverKeyword,
ReadonlyKeyword,
RequireKeyword,
NotKeyword,
NumberKeyword,
ObjectKeyword,
OrKeyword,
SetKeyword,
StringKeyword,
SymbolKeyword,
@ -236,9 +239,12 @@ namespace ts {
IntersectionType,
ParenthesizedType,
ThisType,
TypeOperator,
UnaryType,
BinaryType,
ConditionalType,
IndexedAccessType,
MappedType,
CallType,
LiteralType,
// Binding patterns
ObjectBindingPattern,
@ -415,7 +421,9 @@ namespace ts {
FirstJSDocNode = JSDocTypeExpression,
LastJSDocNode = JSDocTypeLiteral,
FirstJSDocTagNode = JSDocTag,
LastJSDocTagNode = JSDocTypeLiteral
LastJSDocTagNode = JSDocTypeLiteral,
TypeOperator = UnaryType, // backwards compatibility
}
export const enum NodeFlags {
@ -970,12 +978,37 @@ namespace ts {
type: TypeNode;
}
export interface TypeOperatorNode extends TypeNode {
kind: SyntaxKind.TypeOperator;
operator: SyntaxKind.KeyOfKeyword;
export type UnaryTypeOperator =
| SyntaxKind.KeyOfKeyword
| SyntaxKind.NotKeyword;
export interface UnaryTypeNode extends TypeNode {
kind: SyntaxKind.UnaryType | SyntaxKind.TypeOperator; // backwards compatibility
operator: UnaryTypeOperator;
type: TypeNode;
}
export type TypeOperatorNode = UnaryTypeNode; // backwards compatibility
export type BinaryTypeOperator =
| SyntaxKind.ExtendsKeyword
| SyntaxKind.AndKeyword
| SyntaxKind.OrKeyword;
export interface BinaryTypeNode extends TypeNode {
kind: SyntaxKind.BinaryType;
operator: BinaryTypeOperator;
left: TypeNode;
right: TypeNode;
}
export interface ConditionalTypeNode extends TypeNode {
kind: SyntaxKind.ConditionalType;
condition: TypeNode;
whenTrue: TypeNode;
whenFalse: TypeNode;
}
export interface IndexedAccessTypeNode extends TypeNode {
kind: SyntaxKind.IndexedAccessType;
objectType: TypeNode;
@ -991,6 +1024,12 @@ namespace ts {
type?: TypeNode;
}
export interface CallTypeNode extends TypeNode {
kind: SyntaxKind.CallType;
target: TypeNode;
arguments: NodeArray<TypeNode>;
}
export interface LiteralTypeNode extends TypeNode {
kind: SyntaxKind.LiteralType;
literal: Expression;
@ -1524,7 +1563,13 @@ namespace ts {
template: TemplateLiteral;
}
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement;
export type CallLikeExpression =
| CallExpression
| NewExpression
| TaggedTemplateExpression
| Decorator
| JsxOpeningLikeElement
| CallTypeNode;
export interface AsExpression extends Expression {
kind: SyntaxKind.AsExpression;
@ -3141,17 +3186,21 @@ namespace ts {
Intersection = 1 << 17, // Intersection (T & U)
Index = 1 << 18, // keyof T
IndexedAccess = 1 << 19, // T[K]
Negation = 1 << 20, // not T
Binary = 1 << 21, // S extends T, S and T, S or T
Conditional = 1 << 22, // T ? U : V
Call = 1 << 23, // T()
/* @internal */
FreshLiteral = 1 << 20, // Fresh literal type
FreshLiteral = 1 << 24, // Fresh literal type
/* @internal */
ContainsWideningType = 1 << 21, // Type is or contains undefined or null widening type
ContainsWideningType = 1 << 25, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type
ContainsObjectLiteral = 1 << 26, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 23, // Type is or contains the anyFunctionType
NonPrimitive = 1 << 24, // intrinsic object type
ContainsAnyFunctionType = 1 << 27, // Type is or contains the anyFunctionType
NonPrimitive = 1 << 28, // intrinsic object type
/* @internal */
JsxAttributes = 1 << 25, // Jsx attributes type
JsxAttributes = 1 << 29, // Jsx attributes type
/* @internal */
Nullable = Undefined | Null,
@ -3166,16 +3215,18 @@ namespace ts {
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal,
StringLike = String | StringLiteral | Index,
NumberLike = Number | NumberLiteral | Enum,
BooleanLike = Boolean | BooleanLiteral,
BooleanLike = Boolean | BooleanLiteral | Negation | Binary,
EnumLike = Enum | EnumLiteral,
/* @internal */
UnionLike = Union | Conditional,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
StructuredOrTypeVariable = StructuredType | TypeParameter | Index | IndexedAccess,
StructuredOrTypeVariable = StructuredType | TypeParameter | Index | IndexedAccess | Negation,
TypeVariable = TypeParameter | IndexedAccess,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol | NonPrimitive,
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol | NonPrimitive | Negation | Binary | Conditional | Call,
NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
@ -3405,6 +3456,35 @@ namespace ts {
type: TypeVariable | UnionOrIntersectionType;
}
export interface NegationType extends Type {
type: Type;
}
/* @internal */
export interface NegatedType extends Type {
negationType: Type;
}
export interface BinaryType extends Type {
left: Type;
operator: BinaryTypeOperator;
right: Type;
}
export interface ConditionalType extends Type {
condition: Type;
whenTrue: Type;
whenFalse: Type;
}
export interface CallType extends Type {
declaration?: CallTypeNode;
/*@internal*/
resolvedSignature?: Signature;
target: Type;
arguments: Type[];
}
export const enum SignatureKind {
Call,
Construct,
@ -3504,6 +3584,121 @@ namespace ts {
compareTypes: TypeComparer; // Type comparer function
}
/**
* Object used to bind a call-like to a signature.
*/
/*@internal*/
export interface CallBinder<T> {
/**
* Determines whether to skip reporting argument errors.
*/
doNotReportArgumentErrors?: boolean;
/**
* If defined, gets the node used to report errors for the target.
* If not defined, errors cannot be reported for the target.
*/
getErrorNode?(target: T): Node | undefined;
/**
* If defined, determines whether the target was defined in a JavaScript file.
* If not defined, assumes the target was not defiend in JavaScript.
*/
isInJavaScriptFile?(target: T): boolean;
/**
* If defined, gets the contextual type of the target.
* If not defined, it is assumed the target cannot have a contextual type.
*/
getContextualType?(target: T): Type | undefined;
/**
* If defined, gets the contextual mapper for the target.
* If not defined, it is assumed the target cannot have a contextual mapper.
*/
getContextualMapper?(target: T): TypeMapper | undefined;
/**
* If defined, gets the type argument nodes for the target.
* If not defined, it is assumed the target does not supply type arguments.
*/
getTypeArguments?(target: T): NodeArray<TypeNode> | undefined;
/**
* If defined, determines whether type arguments should be checked for the target.
* If not defined, it is assumed type arguments should be checked.
*/
shouldCheckTypeArguments?(target: T): boolean;
/**
* If defined, gets the `this` argument for the target.
* If not defined, the `this` argument is assumed to be `void`.
*/
getThisArgument?(target: T): LeftHandSideExpression | undefined;
/**
* If defined, determines whether to check the `this` argument when checking if a signature is applicable.
* If not defined, assumes the `this` argument should be checked.
*/
shouldCheckThisArgument?(target: T): boolean;
/**
* Gets the number of arguments for the target.
*/
getArgumentCount(target: T, signature?: Signature): number;
/**
* If defined, determines whether the argument at the specified index should be checked.
* If not defined, assumes the argument should be checked.
*/
shouldCheckArgument?(target: T, argIndex: number): boolean;
/**
* If defined, checks the arguments of the call.
*/
checkArguments?(target: T): void;
/**
* Gets the effective type of an argument.
*/
getArgumentType(target: T, argIndex: number, contextualType: Type, contextualMapper: TypeMapper): Type | undefined;
/**
* If defined, gets the node to use when reporting argument errors for the argument at the specified index.
* If not defined, errors are not reported for the argument.
*/
getArgumentErrorNode?(target: T, argIndex: number): Node | undefined;
/**
* If defined, finds the index of the first matching argument.
* If not defined, the argument cannot be found.
*/
findArgumentIndex?(target: T, cb: (arg: Expression) => boolean): number;
/**
* If defined, determines whether an argument is context sensitive.
* If undefined, arguments cannot be context sensitive.
*/
isArgumentContextSensitive?(target: T, argIndex: number): boolean;
/**
* If defined, determines whether the target has the correct arity with respect to a call signature.
* If not defined, it assumed the arity is correct.
*/
hasCorrectArity?(target: T, signature: Signature, signatureHelpTrailingComma?: boolean): boolean;
/**
* If defined, overrides the behavior of `checkApplicableSignature`.
* If not defined, the normal behavior of `checkApplicableSignature` is used.
*/
checkApplicableSignatureOverride?(target: T, signature: Signature, relation: Map<RelationComparisonResult>): boolean;
/**
* If defined, determines whether the target has a trailing comma for use with signature help.
* If not defined, assumes no trailing comma.
*/
hasTrailingComma?(target: T): boolean;
}
/* @internal */
export const enum SpecialPropertyAssignmentKind {
None,

View File

@ -2277,6 +2277,86 @@ namespace ts {
}
}
export function getTypePrecedence(node: TypeNode) {
return getTypeOperatorPrecedence(node.kind, getTypeOperator(node));
}
export function getTypeOperator(node: TypeNode) {
return node.kind === SyntaxKind.BinaryType ? (<BinaryTypeNode>node).operator : node.kind;
}
export function getTypeOperatorPrecedence(nodeKind: SyntaxKind, operatorKind?: SyntaxKind) {
switch (nodeKind) {
// non-array type
case SyntaxKind.AnyKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.TypeReference:
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeLiteral:
case SyntaxKind.TupleType:
case SyntaxKind.ParenthesizedType:
case SyntaxKind.ThisType:
case SyntaxKind.MappedType:
case SyntaxKind.LiteralType:
case SyntaxKind.JSDocAllType:
case SyntaxKind.JSDocUnknownType:
case SyntaxKind.JSDocVariadicType:
case SyntaxKind.JSDocFunctionType:
return 10;
// jsdoc prefix/postfix types
case SyntaxKind.JSDocOptionalType:
case SyntaxKind.JSDocNullableType:
case SyntaxKind.JSDocNonNullableType:
return 9;
// array type
case SyntaxKind.IndexedAccessType:
case SyntaxKind.ArrayType:
return 8;
// unary type
case SyntaxKind.TypeOperator:
return 7;
// intersection type
case SyntaxKind.IntersectionType:
return 6;
// union type
case SyntaxKind.UnionType:
return 5;
// binary type
case SyntaxKind.BinaryType:
switch (operatorKind) {
case SyntaxKind.ExtendsKeyword:
return 4;
case SyntaxKind.AndKeyword:
return 3;
case SyntaxKind.OrKeyword:
return 2;
}
break;
// conditional
case SyntaxKind.ConditionalType:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return 1;
}
return -1;
}
export function createDiagnosticCollection(): DiagnosticCollection {
let nonFileDiagnostics: Diagnostic[] = [];
const fileDiagnostics = createMap<Diagnostic[]>();
@ -4110,7 +4190,7 @@ namespace ts {
return node.kind === SyntaxKind.ThisType;
}
export function isTypeOperatorNode(node: Node): node is TypeOperatorNode {
export function isTypeOperatorNode(node: Node): node is UnaryTypeNode {
return node.kind === SyntaxKind.TypeOperator;
}

View File

@ -389,9 +389,20 @@ namespace ts {
return updateParenthesizedType(<ParenthesizedTypeNode>node,
visitNode((<ParenthesizedTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.TypeOperator:
return updateTypeOperatorNode(<TypeOperatorNode>node,
visitNode((<TypeOperatorNode>node).type, visitor, isTypeNode));
case SyntaxKind.UnaryType:
return updateTypeOperatorNode(<UnaryTypeNode>node,
visitNode((<UnaryTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.BinaryType:
return updateBinaryTypeNode(<BinaryTypeNode>node,
visitNode((<BinaryTypeNode>node).left, visitor, isTypeNode),
visitNode((<BinaryTypeNode>node).right, visitor, isTypeNode));
case SyntaxKind.ConditionalType:
return updateConditionalTypeNode(<ConditionalTypeNode>node,
visitNode((<ConditionalTypeNode>node).condition, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).whenTrue, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).whenFalse, visitor, isTypeNode));
case SyntaxKind.IndexedAccessType:
return updateIndexedAccessTypeNode((<IndexedAccessTypeNode>node),
@ -405,6 +416,11 @@ namespace ts {
visitNode((<MappedTypeNode>node).questionToken, tokenVisitor, isToken),
visitNode((<MappedTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.CallType:
return updateCallType((<CallTypeNode>node),
visitNode((<CallTypeNode>node).target, visitor, isTypeNode),
nodesVisitor((<CallTypeNode>node).arguments, visitor, isTypeNode));
case SyntaxKind.LiteralType:
return updateLiteralTypeNode(<LiteralTypeNode>node,
visitNode((<LiteralTypeNode>node).literal, visitor, isExpression));

View File

@ -18,13 +18,13 @@ interface IHasVisualizationModel {
var xs: IHasVisualizationModel[] = [moduleA];
>xs : IHasVisualizationModel[]
>IHasVisualizationModel : IHasVisualizationModel
>[moduleA] : (typeof moduleA)[]
>[moduleA] : typeof moduleA[]
>moduleA : typeof moduleA
var xs2: typeof moduleA[] = [moduleA];
>xs2 : (typeof moduleA)[]
>xs2 : typeof moduleA[]
>moduleA : typeof moduleA
>[moduleA] : (typeof moduleA)[]
>[moduleA] : typeof moduleA[]
>moduleA : typeof moduleA
=== tests/cases/compiler/aliasUsageInArray_backbone.ts ===

View File

@ -22,8 +22,8 @@ class C {
>foo : string
}
var y = [C, C];
>y : (typeof C)[]
>[C, C] : (typeof C)[]
>y : typeof C[]
>[C, C] : typeof C[]
>C : typeof C
>C : typeof C
@ -31,7 +31,7 @@ var r3 = new y[0]();
>r3 : C
>new y[0]() : C
>y[0] : typeof C
>y : (typeof C)[]
>y : typeof C[]
>0 : 0
var a: { (x: number): number; (x: string): string; };

View File

@ -38,11 +38,11 @@ class FetchUser extends React.Component<IFetchUserProps, any> {
? this.props.children(this.state.result)
>this.props.children(this.state.result) : JSX.Element
>this.props.children : ((user: IUser) => JSX.Element) | (((user: IUser) => JSX.Element) & string) | (((user: IUser) => JSX.Element) & number) | (((user: IUser) => JSX.Element) & true) | (((user: IUser) => JSX.Element) & false) | (((user: IUser) => JSX.Element) & React.ReactElement<any>) | (((user: IUser) => JSX.Element) & (string | number | boolean | any[] | React.ReactElement<any>)[])
>this.props.children : ((user: IUser) => JSX.Element) | ((user: IUser) => JSX.Element) & string | ((user: IUser) => JSX.Element) & number | ((user: IUser) => JSX.Element) & true | ((user: IUser) => JSX.Element) & false | ((user: IUser) => JSX.Element) & React.ReactElement<any> | ((user: IUser) => JSX.Element) & (string | number | boolean | any[] | React.ReactElement<any>)[]
>this.props : IFetchUserProps & { children?: React.ReactNode; }
>this : this
>props : IFetchUserProps & { children?: React.ReactNode; }
>children : ((user: IUser) => JSX.Element) | (((user: IUser) => JSX.Element) & string) | (((user: IUser) => JSX.Element) & number) | (((user: IUser) => JSX.Element) & true) | (((user: IUser) => JSX.Element) & false) | (((user: IUser) => JSX.Element) & React.ReactElement<any>) | (((user: IUser) => JSX.Element) & (string | number | boolean | any[] | React.ReactElement<any>)[])
>children : ((user: IUser) => JSX.Element) | ((user: IUser) => JSX.Element) & string | ((user: IUser) => JSX.Element) & number | ((user: IUser) => JSX.Element) & true | ((user: IUser) => JSX.Element) & false | ((user: IUser) => JSX.Element) & React.ReactElement<any> | ((user: IUser) => JSX.Element) & (string | number | boolean | any[] | React.ReactElement<any>)[]
>this.state.result : any
>this.state : any
>this : this

View File

@ -1,7 +1,7 @@
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(17,5): error TS2322: Type 'A & B' is not assignable to type 'number'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(18,5): error TS2322: Type 'A & B' is not assignable to type 'boolean'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(19,5): error TS2322: Type 'A & B' is not assignable to type 'string'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type 'number & true | number & false' is not assignable to type 'string'.
Type 'number & true' is not assignable to type 'string'.
@ -34,6 +34,6 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Ty
str = num_and_bool;
~~~
!!! error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
!!! error TS2322: Type 'number & true | number & false' is not assignable to type 'string'.
!!! error TS2322: Type 'number & true' is not assignable to type 'string'.
}

View File

@ -4,52 +4,52 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(19,1): e
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(20,1): error TS2322: Type 'B' is not assignable to type 'A & B'.
Type 'B' is not assignable to type 'A'.
Property 'a' is missing in type 'B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(23,1): error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'.
Type 'A' is not assignable to type '(A & B) | (C & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(23,1): error TS2322: Type 'A | B' is not assignable to type 'A & B | C & D'.
Type 'A' is not assignable to type 'A & B | C & D'.
Type 'A' is not assignable to type 'C & D'.
Type 'A' is not assignable to type 'C'.
Property 'c' is missing in type 'A'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(25,1): error TS2322: Type 'C | D' is not assignable to type '(A & B) | (C & D)'.
Type 'C' is not assignable to type '(A & B) | (C & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(25,1): error TS2322: Type 'C | D' is not assignable to type 'A & B | C & D'.
Type 'C' is not assignable to type 'A & B | C & D'.
Type 'C' is not assignable to type 'C & D'.
Type 'C' is not assignable to type 'D'.
Property 'd' is missing in type 'C'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(26,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A & B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(26,1): error TS2322: Type 'A & B | C & D' is not assignable to type 'A & B'.
Type 'C & D' is not assignable to type 'A & B'.
Type 'C & D' is not assignable to type 'A'.
Property 'a' is missing in type 'C & D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(27,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A | B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(27,1): error TS2322: Type 'A & B | C & D' is not assignable to type 'A | B'.
Type 'C & D' is not assignable to type 'A | B'.
Type 'C & D' is not assignable to type 'B'.
Property 'b' is missing in type 'C & D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(28,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C & D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(28,1): error TS2322: Type 'A & B | C & D' is not assignable to type 'C & D'.
Type 'A & B' is not assignable to type 'C & D'.
Type 'A & B' is not assignable to type 'C'.
Property 'c' is missing in type 'A & B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(29,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C | D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(29,1): error TS2322: Type 'A & B | C & D' is not assignable to type 'C | D'.
Type 'A & B' is not assignable to type 'C | D'.
Type 'A & B' is not assignable to type 'D'.
Property 'd' is missing in type 'A & B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(31,1): error TS2322: Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(31,1): error TS2322: Type 'A & B' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'A & B' is not assignable to type 'B & D'.
Type 'A & B' is not assignable to type 'D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(32,1): error TS2322: Type 'A | B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
Type 'A' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(32,1): error TS2322: Type 'A | B' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'A' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'A' is not assignable to type 'B & D'.
Type 'A' is not assignable to type 'B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(33,1): error TS2322: Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(33,1): error TS2322: Type 'C & D' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'C & D' is not assignable to type 'B & D'.
Type 'C & D' is not assignable to type 'B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(34,1): error TS2322: Type 'C | D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
Type 'C' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(34,1): error TS2322: Type 'C | D' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'C' is not assignable to type 'A & C | A & D | B & C | B & D'.
Type 'C' is not assignable to type 'B & D'.
Type 'C' is not assignable to type 'B'.
Property 'b' is missing in type 'C'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(35,1): error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'A & B'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(35,1): error TS2322: Type 'A & C | A & D | B & C | B & D' is not assignable to type 'A & B'.
Type 'A & C' is not assignable to type 'A & B'.
Type 'A & C' is not assignable to type 'B'.
Property 'b' is missing in type 'A & C'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'C & D'.
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): error TS2322: Type 'A & C | A & D | B & C | B & D' is not assignable to type 'C & D'.
Type 'A & C' is not assignable to type 'C & D'.
Type 'A & C' is not assignable to type 'D'.
Property 'd' is missing in type 'A & C'.
@ -88,77 +88,77 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e
x = anb; // Ok
x = aob;
~
!!! error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'.
!!! error TS2322: Type 'A' is not assignable to type '(A & B) | (C & D)'.
!!! error TS2322: Type 'A | B' is not assignable to type 'A & B | C & D'.
!!! error TS2322: Type 'A' is not assignable to type 'A & B | C & D'.
!!! error TS2322: Type 'A' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A' is not assignable to type 'C'.
!!! error TS2322: Property 'c' is missing in type 'A'.
x = cnd; // Ok
x = cod;
~
!!! error TS2322: Type 'C | D' is not assignable to type '(A & B) | (C & D)'.
!!! error TS2322: Type 'C' is not assignable to type '(A & B) | (C & D)'.
!!! error TS2322: Type 'C | D' is not assignable to type 'A & B | C & D'.
!!! error TS2322: Type 'C' is not assignable to type 'A & B | C & D'.
!!! error TS2322: Type 'C' is not assignable to type 'C & D'.
!!! error TS2322: Type 'C' is not assignable to type 'D'.
!!! error TS2322: Property 'd' is missing in type 'C'.
anb = x;
~~~
!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A & B'.
!!! error TS2322: Type 'A & B | C & D' is not assignable to type 'A & B'.
!!! error TS2322: Type 'C & D' is not assignable to type 'A & B'.
!!! error TS2322: Type 'C & D' is not assignable to type 'A'.
!!! error TS2322: Property 'a' is missing in type 'C & D'.
aob = x;
~~~
!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'A | B'.
!!! error TS2322: Type 'A & B | C & D' is not assignable to type 'A | B'.
!!! error TS2322: Type 'C & D' is not assignable to type 'A | B'.
!!! error TS2322: Type 'C & D' is not assignable to type 'B'.
!!! error TS2322: Property 'b' is missing in type 'C & D'.
cnd = x;
~~~
!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & B | C & D' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'C'.
!!! error TS2322: Property 'c' is missing in type 'A & B'.
cod = x;
~~~
!!! error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C | D'.
!!! error TS2322: Type 'A & B | C & D' is not assignable to type 'C | D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'C | D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'D'.
!!! error TS2322: Property 'd' is missing in type 'A & B'.
y = anb;
~
!!! error TS2322: Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'A & B' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'B & D'.
!!! error TS2322: Type 'A & B' is not assignable to type 'D'.
y = aob;
~
!!! error TS2322: Type 'A | B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'A' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'A | B' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'A' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'A' is not assignable to type 'B & D'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
y = cnd;
~
!!! error TS2322: Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'C & D' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'C & D' is not assignable to type 'B & D'.
!!! error TS2322: Type 'C & D' is not assignable to type 'B'.
y = cod;
~
!!! error TS2322: Type 'C | D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'C' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
!!! error TS2322: Type 'C | D' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'C' is not assignable to type 'A & C | A & D | B & C | B & D'.
!!! error TS2322: Type 'C' is not assignable to type 'B & D'.
!!! error TS2322: Type 'C' is not assignable to type 'B'.
!!! error TS2322: Property 'b' is missing in type 'C'.
anb = y;
~~~
!!! error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'A & B'.
!!! error TS2322: Type 'A & C | A & D | B & C | B & D' is not assignable to type 'A & B'.
!!! error TS2322: Type 'A & C' is not assignable to type 'A & B'.
!!! error TS2322: Type 'A & C' is not assignable to type 'B'.
!!! error TS2322: Property 'b' is missing in type 'A & C'.
aob = y; // Ok
cnd = y;
~~~
!!! error TS2322: Type '(A & C) | (A & D) | (B & C) | (B & D)' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & C | A & D | B & C | B & D' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & C' is not assignable to type 'C & D'.
!!! error TS2322: Type 'A & C' is not assignable to type 'D'.
!!! error TS2322: Property 'd' is missing in type 'A & C'.

View File

@ -205,7 +205,7 @@ type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
>Options : Options
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
>Q41 : (true & "yes") | (true & "no") | (false & "yes") | (false & "no")
>Q41 : true & "yes" | true & "no" | false & "yes" | false & "no"
>Shape : Shape
>Options : Options

View File

@ -38,7 +38,7 @@ var {...rest4 } = nullAndUndefinedUnion;
>nullAndUndefinedUnion : null | undefined
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null;
>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null
>unionWithIntersection : { n: number; } & { s: string; } & undefined | null
>n : number
>s : string
>null : null
@ -50,5 +50,5 @@ var rest5: { n: number, s: string };
var {...rest5 } = unionWithIntersection;
>rest5 : { n: number; s: string; }
>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null
>unionWithIntersection : { n: number; } & { s: string; } & undefined | null

View File

@ -1,4 +1,4 @@
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(18,10): error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(18,10): error TS2678: Type 'number & true | number & false' is not comparable to type 'string & number'.
Type 'number & false' is not comparable to type 'string & number'.
Type 'number & false' is not comparable to type 'string'.
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(22,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'.
@ -24,7 +24,7 @@ tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithInterse
// Overlap in constituents
case numAndBool:
~~~~~~~~~~
!!! error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
!!! error TS2678: Type 'number & true | number & false' is not comparable to type 'string & number'.
!!! error TS2678: Type 'number & false' is not comparable to type 'string & number'.
!!! error TS2678: Type 'number & false' is not comparable to type 'string'.
break;

View File

@ -416,7 +416,7 @@ type ObjectDescriptor<D, M> = {
>D : D
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
>methods : (M & ThisType<D & M>) | undefined
>methods : M & ThisType<D & M> | undefined
>M : M
>ThisType : ThisType<T>
>D : D

View File

@ -1,4 +1,4 @@
tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'.
tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: false; } & { children?: ReactNode; } | IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'.
Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'.
Type '{ editable: true; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'.
Property 'onEdit' is missing in type '{ editable: true; }'.
@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(13,24): error TS2322: Type '{ editable: tru
// Error
let x = <TextComponent editable={true} />
~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ editable: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: false; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })'.
!!! error TS2322: Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: false; } & { children?: ReactNode; } | IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'.
!!! error TS2322: Type '{ editable: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TextComponent> & { editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; }'.
!!! error TS2322: Type '{ editable: true; }' is not assignable to type '{ editable: true; onEdit: (newText: string) => void; }'.
!!! error TS2322: Property 'onEdit' is missing in type '{ editable: true; }'.

View File

@ -1,4 +1,4 @@
tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type '{ x: "hi"; }' is not assignable to type '(IntrinsicAttributes & { x: number; }) | (IntrinsicAttributes & { x: boolean; })'.
tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: number; } | IntrinsicAttributes & { x: boolean; }'.
Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
Types of property 'x' are incompatible.
@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type '{ x: "hi"; }' i
var SFCComp = SFC1 || SFC2;
<SFCComp x={"hi"}/>
~~~~~~~~
!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type '(IntrinsicAttributes & { x: number; }) | (IntrinsicAttributes & { x: boolean; })'.
!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: number; } | IntrinsicAttributes & { x: boolean; }'.
!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
!!! error TS2322: Types of property 'x' are incompatible.

View File

@ -1,4 +1,4 @@
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type '{ x: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes<RC1> & { x: number; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; })'.
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC1> & { x: number; } & { children?: ReactNode; } | IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; }'.
Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; }'.
Type '{ x: true; }' is not assignable to type '{ x: string; }'.
Types of property 'x' are incompatible.
@ -41,7 +41,7 @@ tests/cases/conformance/jsx/file.tsx(34,22): error TS2559: Type '{ prop: true; }
// Error
let a = <RCComp x />;
~
!!! error TS2322: Type '{ x: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes<RC1> & { x: number; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; })'.
!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC1> & { x: number; } & { children?: ReactNode; } | IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; }'.
!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC2> & { x: string; } & { children?: ReactNode; }'.
!!! error TS2322: Type '{ x: true; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Types of property 'x' are incompatible.

View File

@ -111,7 +111,7 @@ function isB(toTest: any): toTest is B {
// a function that turns an A into an A & B
function union(a: A): A & B | null {
>union : (a: A) => (A & B) | null
>union : (a: A) => A & B | null
>a : A
>A : A
>A : A

View File

@ -25,7 +25,7 @@ if (!(result instanceof RegExp)) {
} else if (!result.global) {
>!result.global : boolean
>result.global : (string & true) | (string & false)
>result.global : string & true | string & false
>result : I & RegExp
>global : (string & true) | (string & false)
>global : string & true | string & false
}