Early support for unique symbol type

This commit is contained in:
Ron Buckton
2017-05-04 14:40:03 -07:00
parent 64fd857b0d
commit d8ae9c0e36
5 changed files with 170 additions and 55 deletions

View File

@@ -2331,6 +2331,9 @@ namespace ts {
if (type.flags & TypeFlags.BooleanLiteral) {
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
}
if (type.flags & TypeFlags.Unique) {
return <SymbolTypeNode>createToken(SyntaxKind.SymbolType);
}
if (type.flags & TypeFlags.EnumLiteral) {
const name = symbolToName(type.symbol, /*expectsIdentifier*/ false);
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
@@ -3080,6 +3083,11 @@ namespace ts {
else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) {
writeAnonymousType(<ObjectType>type, nextFlags);
}
else if (type.flags & TypeFlags.Unique) {
writeKeyword(writer, SyntaxKind.SymbolKeyword);
writePunctuation(writer, SyntaxKind.OpenParenToken);
writePunctuation(writer, SyntaxKind.CloseParenToken);
}
else if (type.flags & TypeFlags.StringOrNumberLiteral) {
writer.writeStringLiteral(literalTypeToString(<LiteralType>type));
}
@@ -5193,7 +5201,7 @@ namespace ts {
resolveDynamicMembersOfNode(node, (<ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode>node).members, symbolTable);
break;
case SyntaxKind.ObjectLiteralExpression:
resolveDynamicMembersOfNode(node, (<ObjectLiteralExpression>node).properties, symbolTable);
resolveDynamicMembersOfNode(node, (<ObjectLiteralExpression>node).properties, symbolTable);
break;
}
}
@@ -5234,9 +5242,10 @@ namespace ts {
function resolveDynamicMember(symbolTable: SymbolTable, parent: Symbol, member: ClassElement | TypeElement | ObjectLiteralElement, includes: SymbolFlags, excludes: SymbolFlags) {
Debug.assert(isComputedPropertyName(member.name));
const nameType = checkComputedPropertyName(<ComputedPropertyName>member.name);
if (nameType.flags & TypeFlags.StringOrNumberLiteral) {
// TODO(rbuckton): ESSymbolLiteral
const memberName = (<LiteralType>nameType).text;
if (nameType.flags & (TypeFlags.StringOrNumberLiteral | TypeFlags.Unique)) {
const memberName = nameType.flags & TypeFlags.Unique
? `__@@symbol@${nameType.symbol.id}@${nameType.symbol.name}`
: (<LiteralType>nameType).text;
let symbol = symbolTable.get(memberName);
if (!symbol) {
symbolTable.set(memberName, symbol = createSymbol(SymbolFlags.Dynamic, memberName));
@@ -5244,10 +5253,11 @@ namespace ts {
const staticMember = parent.members && parent.members.get(memberName);
if (symbol.flags & excludes || staticMember) {
const declarations = staticMember ? concatenate(staticMember.declarations, symbol.declarations) : symbol.declarations;
const name = nameType.flags & TypeFlags.Unique ? `[${entityNameToString(<EntityNameExpression>(<ComputedPropertyName>member.name).expression)}]` : memberName;
forEach(declarations, declaration => {
error(declaration.name || declaration, Diagnostics.Duplicate_identifier_0, memberName);
error(declaration.name || declaration, Diagnostics.Duplicate_identifier_0, name);
});
error(member.name || member, Diagnostics.Duplicate_identifier_0, memberName);
error(member.name || member, Diagnostics.Duplicate_identifier_0, name);
symbol = createSymbol(SymbolFlags.Dynamic, memberName);
}
addDeclarationToSymbol(symbol, member, includes);
@@ -5912,7 +5922,7 @@ namespace ts {
t.flags & TypeFlags.StringLike ? globalStringType :
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) :
t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) :
t.flags & TypeFlags.NonPrimitive ? emptyObjectType :
t;
}
@@ -7404,7 +7414,7 @@ namespace ts {
return getTypeOfSymbol(prop);
}
}
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike)) {
if (isTypeAny(objectType)) {
return anyType;
}
@@ -7683,6 +7693,27 @@ namespace ts {
return links.resolvedType;
}
function getTypeFromSymbolTypeNode(node: SymbolTypeNode): Type {
const parent = node.parent;
if (parent.kind === SyntaxKind.VariableDeclaration ||
parent.kind === SyntaxKind.PropertyDeclaration ||
parent.kind === SyntaxKind.PropertySignature ||
parent.kind === SyntaxKind.PropertyAssignment) {
const symbol = getSymbolOfNode(parent);
if (symbol) return getUniqueTypeForSymbol(symbol);
}
return esSymbolType;
}
function getUniqueTypeForSymbol(symbol: Symbol) {
const links = getSymbolLinks(symbol);
if (!links.type) {
links.type = createType(TypeFlags.Unique);
links.type.symbol = symbol;
}
return links.type;
}
function getTypeFromJSDocVariadicType(node: JSDocVariadicType): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
@@ -7753,6 +7784,8 @@ namespace ts {
return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
case SyntaxKind.JSDocLiteralType:
return getTypeFromLiteralTypeNode((<JSDocLiteralType>node).literal);
case SyntaxKind.SymbolType:
return getTypeFromSymbolTypeNode(<SymbolTypeNode>node);
case SyntaxKind.TypeReference:
case SyntaxKind.JSDocTypeReference:
return getTypeFromTypeReference(<TypeReferenceNode>node);
@@ -8556,11 +8589,13 @@ namespace ts {
if (source.flags & TypeFlags.StringLike && target.flags & TypeFlags.String) return true;
if (source.flags & TypeFlags.NumberLike && target.flags & TypeFlags.Number) return true;
if (source.flags & TypeFlags.BooleanLike && target.flags & TypeFlags.Boolean) return true;
if (source.flags & TypeFlags.ESSymbolLike && target.flags & TypeFlags.ESSymbol) return true;
if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.Enum && (<EnumLiteralType>source).baseType === target) return true;
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && isEnumTypeRelatedTo(<EnumType>source, <EnumType>target, errorReporter)) return true;
if (source.flags & TypeFlags.Undefined && (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void))) return true;
if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.NonPrimitive) return true;
if (source.flags & TypeFlags.Unique || target.flags & TypeFlags.Unique) return false;
if (relation === assignableRelation || relation === comparableRelation) {
if (source.flags & TypeFlags.Any) return true;
if ((source.flags & TypeFlags.Number | source.flags & TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true;
@@ -10772,7 +10807,7 @@ namespace ts {
if (flags & TypeFlags.Null) {
return TypeFacts.NullFacts;
}
if (flags & TypeFlags.ESSymbol) {
if (flags & TypeFlags.ESSymbolLike) {
return strictNullChecks ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts;
}
if (flags & TypeFlags.NonPrimitive) {
@@ -13130,7 +13165,7 @@ namespace ts {
// This will allow types number, string, symbol or any. It will also allow enums, the unknown
// type, and any union of these types (like string | number).
if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbolLike)) {
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
}
else {
@@ -13174,7 +13209,7 @@ namespace ts {
let offset = 0;
for (let i = 0; i < node.properties.length; i++) {
const memberDecl = node.properties[i];
let member = memberDecl.symbol;
let member = getSymbolOfNode(memberDecl);
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
isObjectLiteralMethod(memberDecl)) {
@@ -13259,7 +13294,7 @@ namespace ts {
checkNodeDeferred(memberDecl);
}
if (hasDynamicName(memberDecl)) {
if (hasDynamicName(memberDecl) && !isLiteralDynamicName(<ComputedPropertyName>memberDecl.name)) {
if (isNumericName(memberDecl.name)) {
hasComputedNumberProperty = true;
}
@@ -14407,7 +14442,7 @@ namespace ts {
}
// Make sure the property type is the primitive symbol type
if ((expressionType.flags & TypeFlags.ESSymbol) === 0) {
if ((expressionType.flags & TypeFlags.ESSymbolLike) === 0) {
if (reportError) {
error(expression, Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, getTextOfNode(expression));
}
@@ -15011,7 +15046,7 @@ namespace ts {
case SyntaxKind.ComputedPropertyName:
const nameType = checkComputedPropertyName(<ComputedPropertyName>element.name);
if (isTypeOfKind(nameType, TypeFlags.ESSymbol)) {
if (isTypeOfKind(nameType, TypeFlags.ESSymbolLike)) {
return nameType;
}
else {
@@ -15824,14 +15859,46 @@ namespace ts {
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
}
return getReturnTypeOfSignature(signature);
const returnType = getReturnTypeOfSignature(signature);
// Treat any call to the global 'Symbol' function that is part of a variable or property
// as a fresh unique symbol literal type.
if (returnType.flags & TypeFlags.ESSymbolLike && isSymbolOrSymbolForCall(node)) {
const parent = skipParentheses(node).parent;
if (parent.kind === SyntaxKind.VariableDeclaration ||
parent.kind === SyntaxKind.PropertyDeclaration ||
parent.kind === SyntaxKind.PropertyAssignment) {
const symbol = getSymbolOfNode(parent);
if (symbol) return getUniqueTypeForSymbol(symbol);
}
}
return returnType;
}
function isSymbolOrSymbolForCall(node: Node) {
if (!isCallExpression(node)) return false;
let left = node.expression;
if (isPropertyAccessExpression(left) && left.name.text === "for") {
left = left.expression;
}
if (!isIdentifier(left) || left.text !== "Symbol") {
return false;
}
// make sure `Symbol` is the global symbol
const globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false);
if (!globalESSymbol) {
return false;
}
return globalESSymbol === resolveName(left, "Symbol", SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
}
function isCommonJsRequire(node: Node) {
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
return false;
}
// Make sure require is not a local function
// Make sure require is not a local function
const resolvedRequire = resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
if (!resolvedRequire) {
// project does not contain symbol named 'require' - assume commonjs require
@@ -16498,7 +16565,7 @@ namespace ts {
case SyntaxKind.MinusToken:
case SyntaxKind.TildeToken:
checkNonNullType(operandType, node.operand);
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbolLike)) {
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
}
return numberType;
@@ -16618,7 +16685,7 @@ namespace ts {
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
// and the right operand to be of type Any, an object type, or a type parameter type.
// The result is always of the Boolean primitive type.
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbolLike))) {
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive)) {
@@ -17022,8 +17089,8 @@ namespace ts {
// Return true if there was no error, false if there was an error.
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
const offendingSymbolOperand =
maybeTypeOfKind(leftType, TypeFlags.ESSymbol) ? left :
maybeTypeOfKind(rightType, TypeFlags.ESSymbol) ? right :
maybeTypeOfKind(leftType, TypeFlags.ESSymbolLike) ? left :
maybeTypeOfKind(rightType, TypeFlags.ESSymbolLike) ? right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
@@ -17303,7 +17370,7 @@ namespace ts {
function getTypeOfExpression(node: Expression, cache?: boolean) {
// Optimize for the common case of a call to a function with a single non-generic call
// signature where we can just fetch the return type without checking the arguments.
if (node.kind === SyntaxKind.CallExpression && (<CallExpression>node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
if (node.kind === SyntaxKind.CallExpression && (<CallExpression>node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteral*/ true) && !isSymbolOrSymbolForCall(node)) {
const funcType = checkNonNullExpression((<CallExpression>node).expression);
const signature = getSingleCallSignature(funcType);
if (signature && !signature.typeParameters) {
@@ -18160,6 +18227,10 @@ namespace ts {
checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint);
}
function checkSymbolType(node: SymbolTypeNode) {
checkGrammarSymbolTypeNode(node);
}
function isPrivateWithinAmbient(node: Node): boolean {
return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node);
}
@@ -21607,6 +21678,8 @@ namespace ts {
return checkIndexedAccessType(<IndexedAccessTypeNode>node);
case SyntaxKind.MappedType:
return checkMappedType(<MappedTypeNode>node);
case SyntaxKind.SymbolType:
return checkSymbolType(<SymbolTypeNode>node);
case SyntaxKind.FunctionDeclaration:
return checkFunctionDeclaration(<FunctionDeclaration>node);
case SyntaxKind.Block:
@@ -22754,7 +22827,7 @@ namespace ts {
else if (isTupleType(type)) {
return TypeReferenceSerializationKind.ArrayLikeType;
}
else if (isTypeOfKind(type, TypeFlags.ESSymbol)) {
else if (isTypeOfKind(type, TypeFlags.ESSymbolLike)) {
return TypeReferenceSerializationKind.ESSymbolType;
}
else if (isFunctionType(type)) {
@@ -22840,9 +22913,8 @@ namespace ts {
function isLiteralDynamicName(name: ComputedPropertyName) {
name = getParseTreeNode(name, isComputedPropertyName);
if (name) {
// TODO(rbuckton): ESSymbolLiteral
const nameType = checkComputedPropertyName(name);
return (nameType.flags & TypeFlags.StringOrNumberLiteral) !== 0;
return (nameType.flags & (TypeFlags.StringOrNumberLiteral | TypeFlags.Unique)) !== 0;
}
return false;
}
@@ -23897,10 +23969,24 @@ namespace ts {
}
}
function checkGrammarSymbolTypeNode(node: SymbolTypeNode) {
const parent = node.parent;
if (parent.kind !== SyntaxKind.VariableDeclaration &&
parent.kind !== SyntaxKind.PropertyDeclaration &&
parent.kind !== SyntaxKind.PropertySignature &&
parent.kind !== SyntaxKind.PropertyAssignment) {
return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_are_only_allowed_on_variables_and_properties);
}
if (parent.kind === SyntaxKind.VariableDeclaration &&
(<VariableDeclaration>parent).name.kind !== SyntaxKind.Identifier) {
return grammarErrorOnNode(node, Diagnostics.Unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
}
}
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
if (isDynamicName(node)) {
if (!isEntityNameExpression((<ComputedPropertyName>node).expression) ||
(checkExpressionCached((<ComputedPropertyName>node).expression).flags & TypeFlags.StringOrNumberLiteral) === 0) {
(checkExpressionCached((<ComputedPropertyName>node).expression).flags & (TypeFlags.StringOrNumberLiteral | TypeFlags.Unique)) === 0) {
return grammarErrorOnNode(node, message);
}
}

View File

@@ -417,6 +417,8 @@ namespace ts {
case SyntaxKind.ThisType:
case SyntaxKind.LiteralType:
return writeTextOfNode(currentText, type);
case SyntaxKind.SymbolType:
return write("symbol()");
case SyntaxKind.ExpressionWithTypeArguments:
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
case SyntaxKind.TypeReference:
@@ -1297,14 +1299,9 @@ namespace ts {
function emitDynamicName(entityName: EntityNameExpression) {
writer.getSymbolAccessibilityDiagnostic = getVariableDeclarationTypeVisibilityError;
const visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
if (visibilityResult.accessibility !== SymbolAccessibility.Accessible) {
resolver.writeTypeOfExpression(entityName, enclosingDeclaration, TypeFormatFlags.None, writer);
}
else {
handleSymbolAccessibilityError(visibilityResult);
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
writeTextOfNode(currentText, node.name);
}
handleSymbolAccessibilityError(visibilityResult);
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
writeTextOfNode(currentText, node.name);
}
function emitBindingPattern(bindingPattern: BindingPattern) {

View File

@@ -879,6 +879,15 @@
"category": "Error",
"code": 1322
},
"Unique 'symbol()' types are only allowed on variables and properties.": {
"category": "Error",
"code": 1323
},
"Unique 'symbol()' types may not be used on a variable declaration with a binding name.": {
"category": "Error",
"code": 1324
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300

View File

@@ -2499,6 +2499,19 @@ namespace ts {
return token() === SyntaxKind.DotToken ? undefined : node;
}
function parseSymbolType(): TypeNode | undefined {
const fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.SymbolKeyword);
if (token() === SyntaxKind.DotToken) return undefined;
if (parseOptional(SyntaxKind.OpenParenToken)) {
parseExpected(SyntaxKind.CloseParenToken);
return finishNode(<SymbolTypeNode>createNode(SyntaxKind.SymbolType, fullStart));
}
else {
return finishNode(<TypeNode>createNode(SyntaxKind.SymbolKeyword, fullStart));
}
}
function parseLiteralTypeNode(): LiteralTypeNode {
const node = <LiteralTypeNode>createNode(SyntaxKind.LiteralType);
node.literal = parseSimpleUnaryExpression();
@@ -2516,13 +2529,15 @@ namespace ts {
case SyntaxKind.StringKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ObjectKeyword:
// If these are followed by a dot, then parse these out as a dotted type reference instead.
const node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReference();
return tryParse(parseKeywordAndNoDot)
|| parseTypeReference();
case SyntaxKind.SymbolKeyword:
return tryParse(parseSymbolType)
|| parseTypeReference();
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
case SyntaxKind.TrueKeyword:

View File

@@ -242,6 +242,7 @@ namespace ts {
IndexedAccessType,
MappedType,
LiteralType,
SymbolType,
// Binding patterns
ObjectBindingPattern,
ArrayBindingPattern,
@@ -406,7 +407,7 @@ namespace ts {
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypePredicate,
LastTypeNode = LiteralType,
LastTypeNode = SymbolType,
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
FirstToken = Unknown,
@@ -959,6 +960,10 @@ namespace ts {
literal: Expression;
}
export interface SymbolTypeNode extends TypeNode {
kind: SyntaxKind.SymbolType;
}
export interface StringLiteral extends LiteralExpression {
kind: SyntaxKind.StringLiteral;
/* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
@@ -2880,6 +2885,7 @@ namespace ts {
exportsSomeValue?: boolean; // True if module exports some value (not just types)
dynamicMembers?: SymbolTable; // Dynamic members with literal names resolved during check
resolvedMembers?: SymbolTable;
uniqueType?: Type; // ESSymbol Unique type for a symbol.
}
/* @internal */
@@ -2974,31 +2980,32 @@ namespace ts {
BooleanLiteral = 1 << 7,
EnumLiteral = 1 << 8,
ESSymbol = 1 << 9, // Type of symbol primitive introduced in ES6
Void = 1 << 10,
Undefined = 1 << 11,
Null = 1 << 12,
Never = 1 << 13, // Never type
TypeParameter = 1 << 14, // Type parameter
Object = 1 << 15, // Object type
Union = 1 << 16, // Union (T | U)
Intersection = 1 << 17, // Intersection (T & U)
Index = 1 << 18, // keyof T
IndexedAccess = 1 << 19, // T[K]
Unique = 1 << 10, // symbol()
Void = 1 << 11,
Undefined = 1 << 12,
Null = 1 << 13,
Never = 1 << 14, // Never type
TypeParameter = 1 << 15, // Type parameter
Object = 1 << 16, // Object type
Union = 1 << 17, // Union (T | U)
Intersection = 1 << 18, // Intersection (T & U)
Index = 1 << 19, // keyof T
IndexedAccess = 1 << 20, // T[K]
/* @internal */
FreshLiteral = 1 << 20, // Fresh literal type
FreshLiteral = 1 << 21, // Fresh literal type
/* @internal */
ContainsWideningType = 1 << 21, // Type is or contains undefined or null widening type
ContainsWideningType = 1 << 22, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type
ContainsObjectLiteral = 1 << 23, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
NonPrimitive = 1 << 24, // intrinsic object type
ContainsAnyFunctionType = 1 << 24, // Type is or contains object literal type
NonPrimitive = 1 << 25, // intrinsic object type
/* @internal */
JsxAttributes = 1 << 25, // Jsx attributes type
JsxAttributes = 1 << 26, // Jsx attributes type
/* @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BooleanLiteral | EnumLiteral,
Literal = StringLiteral | NumberLiteral | BooleanLiteral | EnumLiteral | Unique,
StringOrNumberLiteral = StringLiteral | NumberLiteral,
/* @internal */
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
@@ -3011,6 +3018,7 @@ namespace ts {
NumberLike = Number | NumberLiteral | Enum | EnumLiteral,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | Unique,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
StructuredOrTypeVariable = StructuredType | TypeParameter | Index | IndexedAccess,
@@ -3018,7 +3026,7 @@ namespace ts {
// '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 | Unique | NonPrimitive,
NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,