Add type predicate helper functions to Type (#23066)

This commit is contained in:
Andy
2018-04-04 08:10:09 -07:00
committed by GitHub
parent db74229a89
commit 1e227c6d77
11 changed files with 79 additions and 26 deletions
@@ -116,13 +116,13 @@ namespace ts.codefix {
else if (type.flags & TypeFlags.Boolean) {
return createFalse();
}
else if (type.flags & TypeFlags.Literal) {
return createLiteral((<LiteralType>type).value);
else if (type.isLiteral()) {
return createLiteral(type.value);
}
else if (type.flags & TypeFlags.Union) {
return firstDefined((<UnionType>type).types, t => getDefaultValueFromType(checker, t));
else if (type.isUnion()) {
return firstDefined(type.types, t => getDefaultValueFromType(checker, t));
}
else if (getObjectFlags(type) & ObjectFlags.Class) {
else if (type.isClass()) {
const classDeclaration = getClassLikeDeclarationOfSymbol(type.symbol);
if (!classDeclaration || hasModifier(classDeclaration, ModifierFlags.Abstract)) return undefined;
+6 -7
View File
@@ -474,10 +474,10 @@ namespace ts.Completions {
function getStringLiteralTypes(type: Type | undefined, typeChecker: TypeChecker, uniques = createMap<true>()): ReadonlyArray<StringLiteralType> | undefined {
if (!type) return emptyArray;
type = skipConstraint(type);
return type.flags & TypeFlags.Union
? flatMap((<UnionType>type).types, t => getStringLiteralTypes(t, typeChecker, uniques))
: type.flags & TypeFlags.StringLiteral && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, (type as StringLiteralType).value)
? [type as StringLiteralType]
return type.isUnion()
? flatMap(type.types, t => getStringLiteralTypes(t, typeChecker, uniques))
: type.isStringLiteral() && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, type.value)
? [type]
: emptyArray;
}
@@ -2202,13 +2202,12 @@ namespace ts.Completions {
* excludes array-like types or callable/constructable types.
*/
function getPropertiesForCompletion(type: Type, checker: TypeChecker, isForAccess: boolean): Symbol[] {
if (!(type.flags & TypeFlags.Union)) {
if (!(type.isUnion())) {
return Debug.assertEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined");
}
const { types } = type as UnionType;
// If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
const filteredTypes = isForAccess ? types : types.filter(memberType =>
const filteredTypes = isForAccess ? type.types : type.types.filter(memberType =>
!(memberType.flags & TypeFlags.Primitive || checker.isArrayLikeType(memberType) || typeHasCallOrConstructSignatures(memberType, checker)));
return Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(filteredTypes), "getAllPossiblePropertiesOfTypes() should all be defined");
}
+5 -5
View File
@@ -1132,8 +1132,8 @@ namespace ts.FindAllReferences.Core {
if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) {
result.push(componentType.symbol);
}
if (componentType.getFlags() & TypeFlags.UnionOrIntersection) {
getSymbolsForClassAndInterfaceComponents(<UnionOrIntersectionType>componentType, result);
if (componentType.isUnionOrIntersection()) {
getSymbolsForClassAndInterfaceComponents(componentType, result);
}
}
return result;
@@ -1567,7 +1567,7 @@ namespace ts.FindAllReferences.Core {
const name = getNameFromPropertyName(node.name);
const symbol = contextualType && name && contextualType.getProperty(name);
return symbol ? [symbol] :
contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((<UnionType>contextualType).types, t => t.getProperty(name)) : emptyArray;
contextualType && contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name)) : emptyArray;
}
/**
@@ -1650,8 +1650,8 @@ namespace ts.FindAllReferences.Core {
const localParentType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression);
return localParentType && localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== symbol.parent
? [localParentType.symbol]
: localParentType && localParentType.flags & TypeFlags.UnionOrIntersection
? getSymbolsForClassAndInterfaceComponents(<UnionOrIntersectionType>localParentType)
: localParentType && localParentType.isUnionOrIntersection()
? getSymbolsForClassAndInterfaceComponents(localParentType)
: undefined;
}
}
+2 -2
View File
@@ -131,8 +131,8 @@ namespace ts.GoToDefinition {
return undefined;
}
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum)) {
return flatMap((<UnionType>type).types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
if (type.isUnion() && !(type.flags & TypeFlags.Enum)) {
return flatMap(type.types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
}
return type.symbol && getDefinitionFromSymbol(typeChecker, type.symbol, node);
+2 -2
View File
@@ -1600,8 +1600,8 @@ namespace ts.refactor.extractSymbol {
const {visitedTypes} = symbolWalker.walkType(type);
for (const visitedType of visitedTypes) {
if (visitedType.flags & TypeFlags.TypeParameter) {
allTypeParameterUsages.set(visitedType.id.toString(), visitedType as TypeParameter);
if (visitedType.isTypeParameter()) {
allTypeParameterUsages.set(visitedType.id.toString(), visitedType);
}
}
}
+29 -3
View File
@@ -431,9 +431,7 @@ namespace ts {
return this.checker.getIndexTypeOfType(this, IndexKind.Number);
}
getBaseTypes(): BaseType[] | undefined {
return this.flags & TypeFlags.Object && this.objectFlags & (ObjectFlags.Class | ObjectFlags.Interface)
? this.checker.getBaseTypes(<InterfaceType><Type>this)
: undefined;
return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined;
}
getNonNullableType(): Type {
return this.checker.getNonNullableType(this);
@@ -444,6 +442,34 @@ namespace ts {
getDefault(): Type | undefined {
return this.checker.getDefaultFromTypeParameter(this);
}
isUnion(): this is UnionType {
return !!(this.flags & TypeFlags.Union);
}
isIntersection(): this is IntersectionType {
return !!(this.flags & TypeFlags.Intersection);
}
isUnionOrIntersection(): this is UnionOrIntersectionType {
return !!(this.flags & TypeFlags.UnionOrIntersection);
}
isLiteral(): this is LiteralType {
return !!(this.flags & TypeFlags.Literal);
}
isStringLiteral(): this is StringLiteralType {
return !!(this.flags & TypeFlags.StringLiteral);
}
isNumberLiteral(): this is NumberLiteralType {
return !!(this.flags & TypeFlags.NumberLiteral);
}
isTypeParameter(): this is TypeParameter {
return !!(this.flags & TypeFlags.TypeParameter);
}
isClassOrInterface(): this is InterfaceType {
return !!(getObjectFlags(this) & ObjectFlags.ClassOrInterface);
}
isClass(): this is InterfaceType {
return !!(getObjectFlags(this) & ObjectFlags.Class);
}
}
class SignatureObject implements Signature {
+1 -1
View File
@@ -201,7 +201,7 @@ namespace ts.SymbolDisplay {
// If it is call or construct signature of lambda's write type name
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
displayParts.push(spacePart());
if (!(type.flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous) && type.symbol) {
if (!(getObjectFlags(type) & ObjectFlags.Anonymous) && type.symbol) {
addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.AllowAnyNodeKind | SymbolFormatFlags.WriteTypeParametersOrArguments));
displayParts.push(lineBreakPart());
}
+10
View File
@@ -52,6 +52,16 @@ namespace ts {
getNonNullableType(): Type;
getConstraint(): Type | undefined;
getDefault(): Type | undefined;
isUnion(): this is UnionType;
isIntersection(): this is IntersectionType;
isUnionOrIntersection(): this is UnionOrIntersectionType;
isLiteral(): this is LiteralType;
isStringLiteral(): this is StringLiteralType;
isNumberLiteral(): this is NumberLiteralType;
isTypeParameter(): this is TypeParameter;
isClassOrInterface(): this is InterfaceType;
isClass(): this is InterfaceType;
}
export interface Signature {
+1 -1
View File
@@ -1218,7 +1218,7 @@ namespace ts {
}
export function skipConstraint(type: Type): Type {
return type.flags & TypeFlags.TypeParameter ? type.getConstraint() : type;
return type.isTypeParameter() ? type.getConstraint() : type;
}
export function getNameFromPropertyName(name: PropertyName): string | undefined {
+9
View File
@@ -4007,6 +4007,15 @@ declare namespace ts {
getNonNullableType(): Type;
getConstraint(): Type | undefined;
getDefault(): Type | undefined;
isUnion(): this is UnionType;
isIntersection(): this is IntersectionType;
isUnionOrIntersection(): this is UnionOrIntersectionType;
isLiteral(): this is LiteralType;
isStringLiteral(): this is StringLiteralType;
isNumberLiteral(): this is NumberLiteralType;
isTypeParameter(): this is TypeParameter;
isClassOrInterface(): this is InterfaceType;
isClass(): this is InterfaceType;
}
interface Signature {
getDeclaration(): SignatureDeclaration;
+9
View File
@@ -4260,6 +4260,15 @@ declare namespace ts {
getNonNullableType(): Type;
getConstraint(): Type | undefined;
getDefault(): Type | undefined;
isUnion(): this is UnionType;
isIntersection(): this is IntersectionType;
isUnionOrIntersection(): this is UnionOrIntersectionType;
isLiteral(): this is LiteralType;
isStringLiteral(): this is StringLiteralType;
isNumberLiteral(): this is NumberLiteralType;
isTypeParameter(): this is TypeParameter;
isClassOrInterface(): this is InterfaceType;
isClass(): this is InterfaceType;
}
interface Signature {
getDeclaration(): SignatureDeclaration;