Skip to content

Commit acf75c3

Browse files
committed
Add type relationship functions to checker api
1 parent 3f1ec7a commit acf75c3

File tree

5 files changed

+344
-1
lines changed

5 files changed

+344
-1
lines changed

Jakefile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ var harnessSources = harnessCoreSources.concat([
152152
"transpile.ts",
153153
"reuseProgramStructure.ts",
154154
"cachingInServerLSHost.ts",
155+
"checkerPublicRelationships.ts",
155156
"moduleResolution.ts",
156157
"tsconfigParsing.ts",
157158
"commandLineParsing.ts",

src/compiler/checker.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,59 @@ namespace ts {
103103

104104
getJsxElementAttributesType,
105105
getJsxIntrinsicTagNames,
106-
isOptionalParameter
106+
isOptionalParameter,
107+
108+
isIdenticalTo: (a, b) => checkTypeRelatedTo(a, b, identityRelation, /*errorNode*/undefined),
109+
isSubtypeOf: (a, b) => checkTypeRelatedTo(a, b, subtypeRelation, /*errorNode*/undefined),
110+
isAssignableTo: (a, b) => checkTypeRelatedTo(a, b, assignableRelation, /*errorNode*/undefined),
111+
isComparableTo: areTypesComparable,
112+
isInstantiationOf: (a, b) => {
113+
return a && b && (a.target === b);
114+
},
115+
116+
lookupGlobalType: name => {
117+
const symbol = getSymbol(globals, name, SymbolFlags.Type);
118+
return symbol ? getDeclaredTypeOfSymbol(symbol) : unknownType;
119+
},
120+
lookupGlobalValueType: name => {
121+
const symbol = getSymbol(globals, name, SymbolFlags.Value);
122+
return symbol ? getTypeOfSymbol(symbol) : unknownType;
123+
},
124+
lookupTypeAt: (name, node) => {
125+
const symbol = resolveName(node, name, SymbolFlags.Type, /*nameNotFoundMessage*/undefined, /*nameArg*/undefined);
126+
return symbol ? getDeclaredTypeOfSymbol(symbol) : unknownType;
127+
},
128+
lookupValueTypeAt: (name, node) => {
129+
const symbol = resolveName(node, name, SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/undefined);
130+
return symbol ? getTypeOfSymbol(symbol) : unknownType;
131+
},
132+
getTypeOfSymbol,
133+
134+
getAnyType: () => anyType,
135+
getStringType: () => stringType,
136+
getNumberType: () => numberType,
137+
getBooleanType: () => booleanType,
138+
getVoidType: () => voidType,
139+
getUndefinedType: () => undefinedType,
140+
getNullType: () => nullType,
141+
getESSymbolType: () => esSymbolType,
142+
getNeverType: () => neverType,
143+
getUnknownType: () => unknownType,
144+
getStringLiteralType: (text: string) => {
145+
/* tslint:disable:no-null-keyword */
146+
Debug.assert(text !== undefined && text !== null);
147+
/* tslint:enable:no-null-keyword */
148+
return getLiteralTypeForText(TypeFlags.StringLiteral, "" + text);
149+
},
150+
getNumberLiteralType: (text: string) => {
151+
/* tslint:disable:no-null-keyword */
152+
Debug.assert(text !== undefined && text !== null);
153+
/* tslint:enable:no-null-keyword */
154+
Debug.assert(typeof text === "string" || typeof text === "number"); // While not formally part of the function signature, allow coercions from numbers
155+
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + text);
156+
},
157+
getFalseType: () => falseType,
158+
getTrueType: () => trueType,
107159
};
108160

109161
const tupleTypes: Map<TupleType> = {};

src/compiler/types.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,100 @@ namespace ts {
18721872
getJsxIntrinsicTagNames(): Symbol[];
18731873
isOptionalParameter(node: ParameterDeclaration): boolean;
18741874

1875+
/**
1876+
* Two types are considered identical when
1877+
* - they are both the `any` type,
1878+
* - they are the same primitive type,
1879+
* - they are the same type parameter,
1880+
* - they are union types with identical sets of constituent types, or
1881+
* - they are intersection types with identical sets of constituent types, or
1882+
* - they are object types with identical sets of members.
1883+
*
1884+
* This relationship is bidirectional.
1885+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.2) for more information.
1886+
*/
1887+
isIdenticalTo(a: Type, b: Type): boolean;
1888+
/**
1889+
* `a` is a ___subtype___ of `b` (and `b` is a ___supertype___ of `a`) if `a` has no excess properties with respect to `b`,
1890+
* and one of the following is true:
1891+
* - `a` and `b` are identical types.
1892+
* - `b` is the `any` type.
1893+
* - `a` is the `undefined` type.
1894+
* - `a` is the `null` type and `b` is _not_ the `undefined` type.
1895+
* - `a` is an enum type and `b` is the primitive type `number`.
1896+
* - `a` is a string literal type and `b` is the primitive type `string`.
1897+
* - `a` is a union type and each constituient type of `b` is a subtype of `b`.
1898+
* - `a` is an intersection type and at least one constituent type of `a` is a subtype of `b`.
1899+
* - `b` is a union type and `a` is a subtype of at least one constituent type of `b`.
1900+
* - `b` is an intersection type and `a` is a subtype of each constituent type of `b`.
1901+
* - `a` is a type parameter and the constraint of `a` is a subtype of `b`.
1902+
* - `a` has a subset of the structural members of `b`.
1903+
*
1904+
* This relationship is directional.
1905+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.3) for more information.
1906+
*/
1907+
isSubtypeOf(a: Type, b: Type): boolean;
1908+
/**
1909+
* The assignable relationship differs only from the subtype relationship in that:
1910+
* - the `any` type is assignable to, but not a subtype of, all types
1911+
* - the primitive type `number` is assignable to, but not a subtype of, all enum types, and
1912+
* - an object type without a particular property is assignable to an object type in which that property is optional.
1913+
*
1914+
* This relationship is directional.
1915+
* See [here](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.11.4) for more information.
1916+
*/
1917+
isAssignableTo(a: Type, b: Type): boolean;
1918+
/**
1919+
* True if `a` is assignable to `b`, or `b` is assignable to `a`. Additionally, all unions with
1920+
* overlapping constituient types are comparable, and unit types in the same domain are comparable.
1921+
* This relationship is bidirectional.
1922+
*/
1923+
isComparableTo(a: Type, b: Type): boolean;
1924+
/**
1925+
* Not a formal relationship - returns true if a is an instantiation of the generic type b
1926+
*/
1927+
isInstantiationOf(a: GenericType, b: GenericType): boolean;
1928+
1929+
/**
1930+
* Returns the declared type of the globally named symbol with meaning SymbolFlags.Type
1931+
* Returns the unknown type on failure.
1932+
*/
1933+
lookupGlobalType(name: string): Type;
1934+
/**
1935+
* Returns the declared type of the globally named symbol with meaning SymbolFlags.Value
1936+
* Returns the unknown type on failure.
1937+
*/
1938+
lookupGlobalValueType(name: string): Type;
1939+
/**
1940+
* Returns the declared type of the named symbol lexically at the position specified with meaning SymbolFlags.Type
1941+
* Returns the unknown type on failure.
1942+
*/
1943+
lookupTypeAt(name: string, position: Node): Type;
1944+
/**
1945+
* Returns the declared type of the named symbol lexically at the position specified with meaning SymbolFlags.Value
1946+
* Returns the unknown type on failure.
1947+
*/
1948+
lookupValueTypeAt(name: string, position: Node): Type;
1949+
/**
1950+
* Returns the type of a symbol
1951+
*/
1952+
getTypeOfSymbol(symbol: Symbol): Type;
1953+
1954+
getAnyType(): Type;
1955+
getStringType(): Type;
1956+
getNumberType(): Type;
1957+
getBooleanType(): Type;
1958+
getVoidType(): Type;
1959+
getUndefinedType(): Type;
1960+
getNullType(): Type;
1961+
getESSymbolType(): Type;
1962+
getNeverType(): Type;
1963+
getUnknownType(): Type;
1964+
getStringLiteralType(text: string): LiteralType;
1965+
getNumberLiteralType(text: string): LiteralType;
1966+
getFalseType(): Type;
1967+
getTrueType(): Type;
1968+
18751969
// Should not be called directly. Should only be accessed through the Program instance.
18761970
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
18771971
/* @internal */ getGlobalDiagnostics(): Diagnostic[];

src/harness/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"./unittests/transpile.ts",
8484
"./unittests/reuseProgramStructure.ts",
8585
"./unittests/cachingInServerLSHost.ts",
86+
"./unittests/checkerPublicRelationships.ts",
8687
"./unittests/moduleResolution.ts",
8788
"./unittests/tsconfigParsing.ts",
8889
"./unittests/commandLineParsing.ts",

0 commit comments

Comments
 (0)