Skip to content

Commit 9167706

Browse files
weswighamSheyne
authored andcommitted
Add type relationship functions to checker api
1 parent 3029b8f commit 9167706

File tree

5 files changed

+343
-1
lines changed

5 files changed

+343
-1
lines changed

Jakefile.js

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ var harnessSources = harnessCoreSources.concat([
115115
"reuseProgramStructure.ts",
116116
"textStorage.ts",
117117
"cachingInServerLSHost.ts",
118+
"checkerPublicRelationships.ts",
118119
"moduleResolution.ts",
119120
"tsconfigParsing.ts",
120121
"commandLineParsing.ts",

src/compiler/checker.ts

+52-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,58 @@ namespace ts {
192192
// since we are only interested in declarations of the module itself
193193
return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
194194
},
195-
getApparentType
195+
getApparentType,
196+
isIdenticalTo: (a, b) => checkTypeRelatedTo(a, b, identityRelation, /*errorNode*/undefined),
197+
isSubtypeOf: (a, b) => checkTypeRelatedTo(a, b, subtypeRelation, /*errorNode*/undefined),
198+
isAssignableTo: (a, b) => checkTypeRelatedTo(a, b, assignableRelation, /*errorNode*/undefined),
199+
isComparableTo: areTypesComparable,
200+
isInstantiationOf: (a, b) => {
201+
return a && b && (a.target === b);
202+
},
203+
204+
lookupGlobalType: name => {
205+
const symbol = getSymbol(globals, name, SymbolFlags.Type);
206+
return symbol ? getDeclaredTypeOfSymbol(symbol) : unknownType;
207+
},
208+
lookupGlobalValueType: name => {
209+
const symbol = getSymbol(globals, name, SymbolFlags.Value);
210+
return symbol ? getTypeOfSymbol(symbol) : unknownType;
211+
},
212+
lookupTypeAt: (name, node) => {
213+
const symbol = resolveName(node, name, SymbolFlags.Type, /*nameNotFoundMessage*/undefined, /*nameArg*/undefined);
214+
return symbol ? getDeclaredTypeOfSymbol(symbol) : unknownType;
215+
},
216+
lookupValueTypeAt: (name, node) => {
217+
const symbol = resolveName(node, name, SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/undefined);
218+
return symbol ? getTypeOfSymbol(symbol) : unknownType;
219+
},
220+
getTypeOfSymbol,
221+
222+
getAnyType: () => anyType,
223+
getStringType: () => stringType,
224+
getNumberType: () => numberType,
225+
getBooleanType: () => booleanType,
226+
getVoidType: () => voidType,
227+
getUndefinedType: () => undefinedType,
228+
getNullType: () => nullType,
229+
getESSymbolType: () => esSymbolType,
230+
getNeverType: () => neverType,
231+
getUnknownType: () => unknownType,
232+
getStringLiteralType: (text: string) => {
233+
/* tslint:disable:no-null-keyword */
234+
Debug.assert(text !== undefined && text !== null);
235+
/* tslint:enable:no-null-keyword */
236+
return getLiteralTypeForText(TypeFlags.StringLiteral, "" + text);
237+
},
238+
getNumberLiteralType: (text: string) => {
239+
/* tslint:disable:no-null-keyword */
240+
Debug.assert(text !== undefined && text !== null);
241+
/* tslint:enable:no-null-keyword */
242+
Debug.assert(typeof text === "string" || typeof text === "number"); // While not formally part of the function signature, allow coercions from numbers
243+
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + text);
244+
},
245+
getFalseType: () => falseType,
246+
getTrueType: () => trueType,
196247
};
197248

198249
const tupleTypes: GenericType[] = [];

src/compiler/types.ts

+94
Original file line numberDiff line numberDiff line change
@@ -2540,6 +2540,100 @@ namespace ts {
25402540

25412541
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
25422542

2543+
/**
2544+
* Two types are considered identical when
2545+
* - they are both the `any` type,
2546+
* - they are the same primitive type,
2547+
* - they are the same type parameter,
2548+
* - they are union types with identical sets of constituent types, or
2549+
* - they are intersection types with identical sets of constituent types, or
2550+
* - they are object types with identical sets of members.
2551+
*
2552+
* This relationship is bidirectional.
2553+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.2) for more information.
2554+
*/
2555+
isIdenticalTo(a: Type, b: Type): boolean;
2556+
/**
2557+
* `a` is a ___subtype___ of `b` (and `b` is a ___supertype___ of `a`) if `a` has no excess properties with respect to `b`,
2558+
* and one of the following is true:
2559+
* - `a` and `b` are identical types.
2560+
* - `b` is the `any` type.
2561+
* - `a` is the `undefined` type.
2562+
* - `a` is the `null` type and `b` is _not_ the `undefined` type.
2563+
* - `a` is an enum type and `b` is the primitive type `number`.
2564+
* - `a` is a string literal type and `b` is the primitive type `string`.
2565+
* - `a` is a union type and each constituient type of `b` is a subtype of `b`.
2566+
* - `a` is an intersection type and at least one constituent type of `a` is a subtype of `b`.
2567+
* - `b` is a union type and `a` is a subtype of at least one constituent type of `b`.
2568+
* - `b` is an intersection type and `a` is a subtype of each constituent type of `b`.
2569+
* - `a` is a type parameter and the constraint of `a` is a subtype of `b`.
2570+
* - `a` has a subset of the structural members of `b`.
2571+
*
2572+
* This relationship is directional.
2573+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.3) for more information.
2574+
*/
2575+
isSubtypeOf(a: Type, b: Type): boolean;
2576+
/**
2577+
* The assignable relationship differs only from the subtype relationship in that:
2578+
* - the `any` type is assignable to, but not a subtype of, all types
2579+
* - the primitive type `number` is assignable to, but not a subtype of, all enum types, and
2580+
* - an object type without a particular property is assignable to an object type in which that property is optional.
2581+
*
2582+
* This relationship is directional.
2583+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.4) for more information.
2584+
*/
2585+
isAssignableTo(a: Type, b: Type): boolean;
2586+
/**
2587+
* True if `a` is assignable to `b`, or `b` is assignable to `a`. Additionally, all unions with
2588+
* overlapping constituient types are comparable, and unit types in the same domain are comparable.
2589+
* This relationship is bidirectional.
2590+
*/
2591+
isComparableTo(a: Type, b: Type): boolean;
2592+
/**
2593+
* Not a formal relationship - returns true if a is an instantiation of the generic type b
2594+
*/
2595+
isInstantiationOf(a: GenericType, b: GenericType): boolean;
2596+
2597+
/**
2598+
* Returns the declared type of the globally named symbol with meaning SymbolFlags.Type
2599+
* Returns the unknown type on failure.
2600+
*/
2601+
lookupGlobalType(name: string): Type;
2602+
/**
2603+
* Returns the declared type of the globally named symbol with meaning SymbolFlags.Value
2604+
* Returns the unknown type on failure.
2605+
*/
2606+
lookupGlobalValueType(name: string): Type;
2607+
/**
2608+
* Returns the declared type of the named symbol lexically at the position specified with meaning SymbolFlags.Type
2609+
* Returns the unknown type on failure.
2610+
*/
2611+
lookupTypeAt(name: string, position: Node): Type;
2612+
/**
2613+
* Returns the declared type of the named symbol lexically at the position specified with meaning SymbolFlags.Value
2614+
* Returns the unknown type on failure.
2615+
*/
2616+
lookupValueTypeAt(name: string, position: Node): Type;
2617+
/**
2618+
* Returns the type of a symbol
2619+
*/
2620+
getTypeOfSymbol(symbol: Symbol): Type;
2621+
2622+
getAnyType(): Type;
2623+
getStringType(): Type;
2624+
getNumberType(): Type;
2625+
getBooleanType(): Type;
2626+
getVoidType(): Type;
2627+
getUndefinedType(): Type;
2628+
getNullType(): Type;
2629+
getESSymbolType(): Type;
2630+
getNeverType(): Type;
2631+
getUnknownType(): Type;
2632+
getStringLiteralType(text: string): LiteralType;
2633+
getNumberLiteralType(text: string): LiteralType;
2634+
getFalseType(): Type;
2635+
getTrueType(): Type;
2636+
25432637
// Should not be called directly. Should only be accessed through the Program instance.
25442638
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
25452639
/* @internal */ getGlobalDiagnostics(): Diagnostic[];

src/harness/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
"./unittests/transpile.ts",
113113
"./unittests/reuseProgramStructure.ts",
114114
"./unittests/cachingInServerLSHost.ts",
115+
"./unittests/checkerPublicRelationships.ts",
115116
"./unittests/moduleResolution.ts",
116117
"./unittests/tsconfigParsing.ts",
117118
"./unittests/commandLineParsing.ts",

0 commit comments

Comments
 (0)