Merge branch 'master' into asyncGenerators

This commit is contained in:
Ron Buckton
2016-11-30 12:47:50 -08:00
191 changed files with 10266 additions and 4239 deletions
+6 -8
View File
@@ -256,7 +256,7 @@ var harnessSources = harnessCoreSources.concat([
"commandLineParsing.ts",
"configurationExtension.ts",
"convertCompilerOptionsFromJson.ts",
"convertTypingOptionsFromJson.ts",
"convertTypeAcquisitionFromJson.ts",
"tsserverProjectSystem.ts",
"compileOnSave.ts",
"typingsInstaller.ts",
@@ -931,7 +931,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
}
if (tests && tests.toLocaleLowerCase() === "rwc") {
testTimeout = 400000;
testTimeout = 800000;
}
colors = process.env.colors || process.env.color;
@@ -1087,12 +1087,10 @@ task("tests-debug", ["setDebugMode", "tests"]);
// Makes the test results the new baseline
desc("Makes the most recent test results the new baseline, overwriting the old baseline");
task("baseline-accept", function () {
acceptBaseline("");
acceptBaseline(localBaseline, refBaseline);
});
function acceptBaseline(containerFolder) {
var sourceFolder = path.join(localBaseline, containerFolder);
var targetFolder = path.join(refBaseline, containerFolder);
function acceptBaseline(sourceFolder, targetFolder) {
console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder);
var files = fs.readdirSync(sourceFolder);
var deleteEnding = '.delete';
@@ -1116,12 +1114,12 @@ function acceptBaseline(containerFolder) {
desc("Makes the most recent rwc test results the new baseline, overwriting the old baseline");
task("baseline-accept-rwc", function () {
acceptBaseline("rwc");
acceptBaseline(localRwcBaseline, refRwcBaseline);
});
desc("Makes the most recent test262 test results the new baseline, overwriting the old baseline");
task("baseline-accept-test262", function () {
acceptBaseline("test262");
acceptBaseline(localTest262Baseline, refTest262Baseline);
});
+13 -9
View File
@@ -1,26 +1,29 @@
var Linter = require("tslint");
var tslint = require("tslint");
var fs = require("fs");
function getLinterOptions() {
return {
configuration: require("../tslint.json"),
formatter: "prose",
formattersDirectory: undefined,
rulesDirectory: "built/local/tslint"
};
}
function lintFileContents(options, path, contents) {
var ll = new Linter(path, contents, options);
return ll.lint();
function getLinterConfiguration() {
return require("../tslint.json");
}
function lintFileAsync(options, path, cb) {
function lintFileContents(options, configuration, path, contents) {
var ll = new tslint.Linter(options);
ll.lint(path, contents, configuration);
return ll.getResult();
}
function lintFileAsync(options, configuration, path, cb) {
fs.readFile(path, "utf8", function (err, contents) {
if (err) {
return cb(err);
}
var result = lintFileContents(options, path, contents);
var result = lintFileContents(options, configuration, path, contents);
cb(undefined, result);
});
}
@@ -30,7 +33,8 @@ process.on("message", function (data) {
case "file":
var target = data.name;
var lintOptions = getLinterOptions();
lintFileAsync(lintOptions, target, function (err, result) {
var lintConfiguration = getLinterConfiguration();
lintFileAsync(lintOptions, lintConfiguration, target, function (err, result) {
if (err) {
process.send({ kind: "error", error: err.toString() });
return;
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
const OPTION_CATCH = "check-catch";
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
+1 -1
View File
@@ -1,4 +1,4 @@
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint/lib";
import * as ts from "typescript";
+2 -2
View File
@@ -598,8 +598,8 @@ namespace ts {
// Binding of JsDocComment should be done before the current block scope container changes.
// because the scope of JsDocComment should not be affected by whether the current node is a
// container or not.
if (isInJavaScriptFile(node) && node.jsDocComments) {
forEach(node.jsDocComments, bind);
if (isInJavaScriptFile(node) && node.jsDoc) {
forEach(node.jsDoc, bind);
}
if (checkUnreachable(node)) {
bindEachChild(node);
+313 -175
View File
@@ -145,7 +145,6 @@ namespace ts {
const voidType = createIntrinsicType(TypeFlags.Void, "void");
const neverType = createIntrinsicType(TypeFlags.Never, "never");
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
const stringOrNumberType = getUnionType([stringType, numberType]);
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@@ -915,6 +914,7 @@ namespace ts {
if (!errorLocation ||
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
!checkAndReportErrorForExtendingInterface(errorLocation) &&
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning)) {
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
}
@@ -1025,6 +1025,18 @@ namespace ts {
}
}
function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
if (meaning === SymbolFlags.Namespace) {
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
if (symbol) {
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, name);
return true;
}
}
return false;
}
function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
@@ -3030,7 +3042,15 @@ namespace ts {
}
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type {
Debug.assert(!!(source.flags & TypeFlags.Object), "Rest types only support object types right now.");
source = filterType(source, t => !(t.flags & TypeFlags.Nullable));
if (source.flags & TypeFlags.Never) {
return emptyObjectType;
}
if (source.flags & TypeFlags.Union) {
return mapType(source, t => getRestType(t, properties, symbol));
}
const members = createMap<Symbol>();
const names = createMap<true>();
for (const name of properties) {
@@ -3071,7 +3091,7 @@ namespace ts {
let type: Type;
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
if (declaration.dotDotDotToken) {
if (!(parentType.flags & TypeFlags.Object)) {
if (!isValidSpreadType(parentType)) {
error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types);
return unknownType;
}
@@ -3144,38 +3164,10 @@ namespace ts {
}
function getTypeForVariableLikeDeclarationFromJSDocComment(declaration: VariableLikeDeclaration) {
const jsDocType = getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration);
if (jsDocType) {
return getTypeFromTypeNode(jsDocType);
const jsdocType = getJSDocType(declaration);
if (jsdocType) {
return getTypeFromTypeNode(jsdocType);
}
}
function getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration: VariableLikeDeclaration): JSDocType {
// First, see if this node has an @type annotation on it directly.
const typeTag = getJSDocTypeTag(declaration);
if (typeTag && typeTag.typeExpression) {
return typeTag.typeExpression.type;
}
if (declaration.kind === SyntaxKind.VariableDeclaration &&
declaration.parent.kind === SyntaxKind.VariableDeclarationList &&
declaration.parent.parent.kind === SyntaxKind.VariableStatement) {
// @type annotation might have been on the variable statement, try that instead.
const annotation = getJSDocTypeTag(declaration.parent.parent);
if (annotation && annotation.typeExpression) {
return annotation.typeExpression.type;
}
}
else if (declaration.kind === SyntaxKind.Parameter) {
// If it's a parameter, see if the parent has a jsdoc comment with an @param
// annotation.
const paramTag = getCorrespondingJSDocParameterTag(<ParameterDeclaration>declaration);
if (paramTag && paramTag.typeExpression) {
return paramTag.typeExpression.type;
}
}
return undefined;
}
@@ -3205,9 +3197,11 @@ namespace ts {
}
}
// A variable declared in a for..in statement is always of type string
// A variable declared in a for..in statement is of type string, or of type keyof T when the
// right hand expression is of a type parameter type.
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
return stringType;
const indexType = getIndexType(checkNonNullExpression((<ForInStatement>declaration.parent.parent).expression));
return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? indexType : stringType;
}
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
@@ -3444,9 +3438,9 @@ namespace ts {
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
// Use JS Doc type if present on parent expression statement
if (declaration.flags & NodeFlags.JavaScriptFile) {
const typeTag = getJSDocTypeTag(declaration.parent);
if (typeTag && typeTag.typeExpression) {
return links.type = getTypeFromTypeNode(typeTag.typeExpression.type);
const jsdocType = getJSDocType(declaration.parent);
if (jsdocType) {
return links.type = getTypeFromTypeNode(jsdocType);
}
}
const declaredTypes = map(symbol.declarations,
@@ -3820,6 +3814,16 @@ namespace ts {
}
baseType = getReturnTypeOfSignature(constructors[0]);
}
// In a JS file, you can use the @augments jsdoc tag to specify a base type with type parameters
const valueDecl = type.symbol.valueDeclaration;
if (valueDecl && isInJavaScriptFile(valueDecl)) {
const augTag = getJSDocAugmentsTag(type.symbol.valueDeclaration);
if (augTag) {
baseType = getTypeFromTypeNode(augTag.typeExpression.type);
}
}
if (baseType === unknownType) {
return;
}
@@ -3828,7 +3832,7 @@ namespace ts {
return;
}
if (type === baseType || hasBaseType(<InterfaceType>baseType, type)) {
error(type.symbol.valueDeclaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
return;
}
@@ -4494,16 +4498,17 @@ namespace ts {
function resolveMappedTypeMembers(type: MappedType) {
const members: SymbolTable = createMap<Symbol>();
let stringIndexInfo: IndexInfo;
let numberIndexInfo: IndexInfo;
// Resolve upfront such that recursive references see an empty object type.
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
// and T as the template type.
// and T as the template type. If K is of the form 'keyof S', the mapped type and S are
// isomorphic and we copy property modifiers from corresponding properties in S.
const typeParameter = getTypeParameterFromMappedType(type);
const constraintType = getConstraintTypeFromMappedType(type);
const isomorphicType = getIsomorphicTypeFromMappedType(type);
const templateType = getTemplateTypeFromMappedType(type);
const isReadonly = !!type.declaration.readonlyToken;
const isOptional = !!type.declaration.questionToken;
const templateReadonly = !!type.declaration.readonlyToken;
const templateOptional = !!type.declaration.questionToken;
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
// if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
// Finally, iterate over the constituents of the resulting iteration type.
@@ -4516,29 +4521,22 @@ namespace ts {
const iterationMapper = createUnaryTypeMapper(typeParameter, t);
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
const propType = instantiateType(templateType, templateMapper);
// If the current iteration type constituent is a literal type, create a property.
// Otherwise, for type string create a string index signature and for type number
// create a numeric index signature.
if (t.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
// If the current iteration type constituent is a string literal type, create a property.
// Otherwise, for type string create a string index signature.
if (t.flags & TypeFlags.StringLiteral) {
const propName = (<LiteralType>t).text;
const isomorphicProp = isomorphicType && getPropertyOfType(isomorphicType, propName);
const isOptional = templateOptional || !!(isomorphicProp && isomorphicProp.flags & SymbolFlags.Optional);
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
prop.type = addOptionality(propType, isOptional);
prop.isReadonly = isReadonly;
prop.type = propType;
prop.isReadonly = templateReadonly || isomorphicProp && isReadonlySymbol(isomorphicProp);
members[propName] = prop;
}
else if (t.flags & TypeFlags.String) {
stringIndexInfo = createIndexInfo(propType, isReadonly);
}
else if (t.flags & TypeFlags.Number) {
numberIndexInfo = createIndexInfo(propType, isReadonly);
stringIndexInfo = createIndexInfo(propType, templateReadonly);
}
});
// If we created both a string and a numeric string index signature, and if the two index
// signatures have identical types, discard the redundant numeric index signature.
if (stringIndexInfo && numberIndexInfo && isTypeIdenticalTo(stringIndexInfo.type, numberIndexInfo.type)) {
numberIndexInfo = undefined;
}
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
}
function getTypeParameterFromMappedType(type: MappedType) {
@@ -4554,10 +4552,15 @@ namespace ts {
function getTemplateTypeFromMappedType(type: MappedType) {
return type.templateType ||
(type.templateType = type.declaration.type ?
instantiateType(getTypeFromTypeNode(type.declaration.type), type.mapper || identityMapper) :
instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) :
unknownType);
}
function getIsomorphicTypeFromMappedType(type: MappedType) {
const constraint = getConstraintDeclaration(getTypeParameterFromMappedType(type));
return constraint.kind === SyntaxKind.TypeOperator ? instantiateType(getTypeFromTypeNode((<TypeOperatorNode>constraint).type), type.mapper || identityMapper) : undefined;
}
function getErasedTemplateTypeFromMappedType(type: MappedType) {
return instantiateType(getTemplateTypeFromMappedType(type), createUnaryTypeMapper(getTypeParameterFromMappedType(type), anyType));
}
@@ -4684,7 +4687,6 @@ namespace ts {
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*checked*/ languageVersion >= ScriptTarget.ES2015) :
t.flags & TypeFlags.Index ? stringOrNumberType :
t;
}
@@ -4897,15 +4899,16 @@ namespace ts {
if (node.type && node.type.kind === SyntaxKind.JSDocOptionalType) {
return true;
}
const paramTags = getJSDocParameterTags(node);
if (paramTags) {
for (const paramTag of paramTags) {
if (paramTag.isBracketed) {
return true;
}
const paramTag = getCorrespondingJSDocParameterTag(node);
if (paramTag) {
if (paramTag.isBracketed) {
return true;
}
if (paramTag.typeExpression) {
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType;
if (paramTag.typeExpression) {
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType;
}
}
}
}
@@ -5694,6 +5697,7 @@ namespace ts {
containsString?: boolean;
containsNumber?: boolean;
containsStringOrNumberLiteral?: boolean;
unionIndex?: number;
}
function binarySearchTypes(types: Type[], type: Type): number {
@@ -5888,6 +5892,9 @@ namespace ts {
typeSet.containsAny = true;
}
else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
if (type.flags & TypeFlags.Union && typeSet.unionIndex === undefined) {
typeSet.unionIndex = typeSet.length;
}
typeSet.push(type);
}
}
@@ -5914,15 +5921,6 @@ namespace ts {
if (types.length === 0) {
return emptyObjectType;
}
for (let i = 0; i < types.length; i++) {
const type = types[i];
if (type.flags & TypeFlags.Union) {
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
return getUnionType(map((<UnionType>type).types, t => getIntersectionType(replaceElement(types, i, t))),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
}
const typeSet = [] as TypeSet;
addTypesToIntersection(typeSet, types);
if (typeSet.containsAny) {
@@ -5931,6 +5929,14 @@ namespace ts {
if (typeSet.length === 1) {
return typeSet[0];
}
const unionIndex = typeSet.unionIndex;
if (unionIndex !== undefined) {
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
const unionType = <UnionType>typeSet[unionIndex];
return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
const id = getTypeListId(typeSet);
let type = intersectionTypes[id];
if (!type) {
@@ -5973,11 +5979,15 @@ namespace ts {
function getIndexType(type: Type): Type {
return type.flags & TypeFlags.TypeParameter ? getIndexTypeForTypeParameter(<TypeParameter>type) :
getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(<MappedType>type) :
type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringOrNumberType :
getIndexInfoOfType(type, IndexKind.Number) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type)]) :
type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType :
getLiteralTypeFromPropertyNames(type);
}
function getIndexTypeOrString(type: Type): Type {
const indexType = getIndexType(type);
return indexType !== neverType ? indexType : stringType;
}
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
const links = getNodeLinks(node);
if (!links.resolvedType) {
@@ -6064,7 +6074,7 @@ namespace ts {
}
const mapper = createUnaryTypeMapper(getTypeParameterFromMappedType(type), indexType);
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
return addOptionality(instantiateType(getTemplateTypeFromMappedType(type), templateMapper), !!type.declaration.questionToken);
return instantiateType(getTemplateTypeFromMappedType(type), templateMapper);
}
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {
@@ -6076,8 +6086,7 @@ namespace ts {
// meaningfully access the properties of the object type. In those cases, we first check that the
// index type is assignable to 'keyof T' for the object type.
if (accessNode) {
const keyType = indexType.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType : indexType;
if (!isTypeAssignableTo(keyType, getIndexType(objectType))) {
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
return unknownType;
}
@@ -6092,11 +6101,11 @@ namespace ts {
const id = objectType.id + "," + indexType.id;
return indexedAccessTypes[id] || (indexedAccessTypes[id] = createIndexedAccessType(objectType, indexType));
}
const apparentType = getApparentType(objectType);
const apparentObjectType = getApparentType(objectType);
if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) {
const propTypes: Type[] = [];
for (const t of (<UnionType>indexType).types) {
const propType = getPropertyTypeForIndexType(apparentType, t, accessNode, /*cacheSymbol*/ false);
const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false);
if (propType === unknownType) {
return unknownType;
}
@@ -6104,7 +6113,7 @@ namespace ts {
}
return getUnionType(propTypes);
}
return getPropertyTypeForIndexType(apparentType, indexType, accessNode, /*cacheSymbol*/ true);
return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true);
}
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
@@ -6162,11 +6171,25 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): ResolvedType | IntrinsicType {
Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread.");
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
left = filterType(left, t => !(t.flags & TypeFlags.Nullable));
if (left.flags & TypeFlags.Never) {
return right;
}
right = filterType(right, t => !(t.flags & TypeFlags.Nullable));
if (right.flags & TypeFlags.Never) {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, isFromObjectLiteral));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, isFromObjectLiteral));
}
const members = createMap<Symbol>();
const skippedPrivateMembers = createMap<boolean>();
let stringIndexInfo: IndexInfo;
@@ -6553,7 +6576,36 @@ namespace ts {
return result;
}
function instantiateMappedType(type: MappedType, mapper: TypeMapper): MappedType {
function instantiateMappedType(type: MappedType, mapper: TypeMapper): Type {
// Check if we have an isomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some
// type parameter T. If so, the mapped type is distributive over a union type and when T is instantiated
// to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for
// isomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
// union type A | undefined, we produce { [P in keyof A]: X } | undefined.
const constraintType = getConstraintTypeFromMappedType(type);
if (constraintType.flags & TypeFlags.Index) {
const typeParameter = (<IndexType>constraintType).type;
const mappedTypeParameter = mapper(typeParameter);
if (typeParameter !== mappedTypeParameter) {
return mapType(mappedTypeParameter, t => {
if (isMappableType(t)) {
const replacementMapper = createUnaryTypeMapper(typeParameter, t);
const combinedMapper = mapper.mappedTypes && mapper.mappedTypes.length === 1 ? replacementMapper : combineTypeMappers(replacementMapper, mapper);
combinedMapper.mappedTypes = mapper.mappedTypes;
return instantiateMappedObjectType(type, combinedMapper);
}
return t;
});
}
}
return instantiateMappedObjectType(type, mapper);
}
function isMappableType(type: Type) {
return type.flags & (TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess);
}
function instantiateMappedObjectType(type: MappedType, mapper: TypeMapper): Type {
const result = <MappedType>createObjectType(ObjectFlags.Mapped | ObjectFlags.Instantiated, type.symbol);
result.declaration = type.declaration;
result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
@@ -7176,13 +7228,6 @@ namespace ts {
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
if (source.flags & TypeFlags.Index) {
// A keyof T is related to a union type containing both string and number
if (maybeTypeOfKind(target, TypeFlags.String) && maybeTypeOfKind(target, TypeFlags.Number)) {
return Ternary.True;
}
}
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
if (reportErrors) {
@@ -7602,25 +7647,30 @@ namespace ts {
// A type [P in S]: X is related to a type [P in T]: Y if T is related to S and X is related to Y.
function mappedTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
if (isGenericMappedType(source) && isGenericMappedType(target)) {
let result: Ternary;
if (relation === identityRelation) {
const readonlyMatches = !(<MappedType>source).declaration.readonlyToken === !(<MappedType>target).declaration.readonlyToken;
const optionalMatches = !(<MappedType>source).declaration.questionToken === !(<MappedType>target).declaration.questionToken;
if (readonlyMatches && optionalMatches) {
if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
return result & isRelatedTo(getErasedTemplateTypeFromMappedType(<MappedType>source), getErasedTemplateTypeFromMappedType(<MappedType>target), reportErrors);
if (isGenericMappedType(target)) {
if (isGenericMappedType(source)) {
let result: Ternary;
if (relation === identityRelation) {
const readonlyMatches = !(<MappedType>source).declaration.readonlyToken === !(<MappedType>target).declaration.readonlyToken;
const optionalMatches = !(<MappedType>source).declaration.questionToken === !(<MappedType>target).declaration.questionToken;
if (readonlyMatches && optionalMatches) {
if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
return result & isRelatedTo(getErasedTemplateTypeFromMappedType(<MappedType>source), getErasedTemplateTypeFromMappedType(<MappedType>target), reportErrors);
}
}
}
}
else {
if (relation === comparableRelation || !(<MappedType>source).declaration.questionToken || (<MappedType>target).declaration.questionToken) {
if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
return result & isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target), reportErrors);
else {
if (relation === comparableRelation || !(<MappedType>source).declaration.questionToken || (<MappedType>target).declaration.questionToken) {
if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
return result & isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target), reportErrors);
}
}
}
}
}
else if (relation !== identityRelation && isEmptyObjectType(resolveStructuredTypeMembers(<ObjectType>target))) {
return Ternary.True;
}
return Ternary.False;
}
@@ -8456,7 +8506,7 @@ namespace ts {
// results for union and intersection types for performance reasons.
function couldContainTypeParameters(type: Type): boolean {
const objectFlags = getObjectFlags(type);
return !!(type.flags & TypeFlags.TypeParameter ||
return !!(type.flags & (TypeFlags.TypeParameter | TypeFlags.IndexedAccess) ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
objectFlags & ObjectFlags.Mapped ||
@@ -8474,8 +8524,59 @@ namespace ts {
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
}
function inferTypes(context: InferenceContext, originalSource: Type, originalTarget: Type) {
const typeParameters = context.signature.typeParameters;
// Infer a suitable input type for an isomorphic mapped type { [P in keyof T]: X }. We construct
// an object type with the same set of properties as the source type, where the type of each
// property is computed by inferring from the source property type to X for a synthetic type
// parameter T[P] (i.e. we treat the type T[P] as the type parameter we're inferring for).
function inferTypeForIsomorphicMappedType(source: Type, target: MappedType): Type {
if (!isMappableType(source)) {
return source;
}
const typeParameter = getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const typeParameterArray = [typeParameter];
const typeInferences = createTypeInferencesObject();
const typeInferencesArray = [typeInferences];
const templateType = getTemplateTypeFromMappedType(target);
const readonlyMask = target.declaration.readonlyToken ? false : true;
const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
const properties = getPropertiesOfType(source);
const members = createSymbolTable(properties);
let hasInferredTypes = false;
for (const prop of properties) {
const inferredPropType = inferTargetType(getTypeOfSymbol(prop));
if (inferredPropType) {
const inferredProp = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | prop.flags & optionalMask, prop.name);
inferredProp.declarations = prop.declarations;
inferredProp.type = inferredPropType;
inferredProp.isReadonly = readonlyMask && isReadonlySymbol(prop);
members[prop.name] = inferredProp;
hasInferredTypes = true;
}
}
let indexInfo = getIndexInfoOfType(source, IndexKind.String);
if (indexInfo) {
const inferredIndexType = inferTargetType(indexInfo.type);
if (inferredIndexType) {
indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly);
hasInferredTypes = true;
}
}
return hasInferredTypes ? createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined) : source;
function inferTargetType(sourceType: Type): Type {
typeInferences.primary = undefined;
typeInferences.secondary = undefined;
inferTypes(typeParameterArray, typeInferencesArray, sourceType, templateType);
const inferences = typeInferences.primary || typeInferences.secondary;
return inferences && getUnionType(inferences, /*subtypeReduction*/ true);
}
}
function inferTypesWithContext(context: InferenceContext, originalSource: Type, originalTarget: Type) {
inferTypes(context.signature.typeParameters, context.inferences, originalSource, originalTarget);
}
function inferTypes(typeParameters: Type[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
let sourceStack: Type[];
let targetStack: Type[];
let depth = 0;
@@ -8543,7 +8644,7 @@ namespace ts {
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, matchingTypes);
}
}
if (target.flags & TypeFlags.TypeParameter) {
if (target.flags & (TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
// If target is a type parameter, make an inference, unless the source type contains
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
@@ -8555,7 +8656,7 @@ namespace ts {
}
for (let i = 0; i < typeParameters.length; i++) {
if (target === typeParameters[i]) {
const inferences = context.inferences[i];
const inferences = typeInferences[i];
if (!inferences.isFixed) {
// Any inferences that are made to a type parameter in a union type are inferior
// to inferences made to a flat (non-union) type. This is because if we infer to
@@ -8569,7 +8670,7 @@ namespace ts {
if (!contains(candidates, source)) {
candidates.push(source);
}
if (!isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
if (target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
inferences.topLevel = false;
}
}
@@ -8617,19 +8718,6 @@ namespace ts {
}
}
else {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (getObjectFlags(source) & ObjectFlags.Mapped) {
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
if (constraintType.flags & TypeFlags.TypeParameter) {
inferFromTypes(getIndexType(source), constraintType);
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
}
source = getApparentType(source);
if (source.flags & TypeFlags.Object) {
if (isInProcess(source, target)) {
@@ -8650,15 +8738,39 @@ namespace ts {
sourceStack[depth] = source;
targetStack[depth] = target;
depth++;
inferFromProperties(source, target);
inferFromSignatures(source, target, SignatureKind.Call);
inferFromSignatures(source, target, SignatureKind.Construct);
inferFromIndexTypes(source, target);
inferFromObjectTypes(source, target);
depth--;
}
}
}
function inferFromObjectTypes(source: Type, target: Type) {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (constraintType.flags & TypeFlags.Index) {
// We're inferring from some source type S to an isomorphic mapped type { [P in keyof T]: X },
// where T is a type parameter. Use inferTypeForIsomorphicMappedType to infer a suitable source
// type and then infer from that type to T.
const index = indexOf(typeParameters, (<IndexType>constraintType).type);
if (index >= 0 && !typeInferences[index].isFixed) {
inferFromTypes(inferTypeForIsomorphicMappedType(source, <MappedType>target), typeParameters[index]);
}
return;
}
if (constraintType.flags & TypeFlags.TypeParameter) {
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
inferFromTypes(getIndexType(source), constraintType);
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
}
inferFromProperties(source, target);
inferFromSignatures(source, target, SignatureKind.Call);
inferFromSignatures(source, target, SignatureKind.Construct);
inferFromIndexTypes(source, target);
}
function inferFromProperties(source: Type, target: Type) {
const properties = getPropertiesOfObjectType(target);
for (const targetProp of properties) {
@@ -9053,7 +9165,7 @@ namespace ts {
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
if (defaultExpression) {
const defaultType = checkExpression(defaultExpression);
const defaultType = getTypeOfExpression(defaultExpression);
return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), defaultType]);
}
return type;
@@ -9080,7 +9192,7 @@ namespace ts {
function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ?
getTypeWithDefault(getAssignedType(node), node.right) :
checkExpression(node.right);
getTypeOfExpression(node.right);
}
function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type {
@@ -9138,7 +9250,7 @@ namespace ts {
// from its initializer, we'll already have cached the type. Otherwise we compute it now
// without caching such that transient types are reflected.
const links = getNodeLinks(node);
return links.resolvedType || checkExpression(node);
return links.resolvedType || getTypeOfExpression(node);
}
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) {
@@ -9198,7 +9310,7 @@ namespace ts {
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
if (clause.kind === SyntaxKind.CaseClause) {
const caseType = getRegularTypeOfLiteralType(checkExpression((<CaseClause>clause).expression));
const caseType = getRegularTypeOfLiteralType(getTypeOfExpression((<CaseClause>clause).expression));
return isUnitType(caseType) ? caseType : undefined;
}
return neverType;
@@ -9303,7 +9415,7 @@ namespace ts {
// we defer subtype reduction until the evolving array type is finalized into a manifest
// array type.
function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType {
const elementType = getBaseTypeOfLiteralType(checkExpression(node));
const elementType = getBaseTypeOfLiteralType(getTypeOfExpression(node));
return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
}
@@ -9364,7 +9476,7 @@ namespace ts {
(<BinaryExpression>parent.parent).operatorToken.kind === SyntaxKind.EqualsToken &&
(<BinaryExpression>parent.parent).left === parent &&
!isAssignmentTarget(parent.parent) &&
isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
return isLengthPushOrUnshift || isElementAssignment;
}
@@ -9526,7 +9638,7 @@ namespace ts {
}
}
else {
const indexType = checkExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
const indexType = getTypeOfExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) {
evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
}
@@ -9751,7 +9863,7 @@ namespace ts {
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
assumeTrue = !assumeTrue;
}
const valueType = checkExpression(value);
const valueType = getTypeOfExpression(value);
if (valueType.flags & TypeFlags.Nullable) {
if (!strictNullChecks) {
return type;
@@ -9838,7 +9950,7 @@ namespace ts {
}
// Check that right operand is a function type with a prototype property
const rightType = checkExpression(expr.right);
const rightType = getTypeOfExpression(expr.right);
if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
return type;
}
@@ -9979,7 +10091,7 @@ namespace ts {
location = location.parent;
}
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
const type = checkExpression(<Expression>location);
const type = getTypeOfExpression(<Expression>location);
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
return type;
}
@@ -10445,9 +10557,9 @@ namespace ts {
}
function getTypeForThisExpressionFromJSDoc(node: Node) {
const typeTag = getJSDocTypeTag(node);
if (typeTag && typeTag.typeExpression && typeTag.typeExpression.type && typeTag.typeExpression.type.kind === SyntaxKind.JSDocFunctionType) {
const jsDocFunctionType = <JSDocFunctionType>typeTag.typeExpression.type;
const jsdocType = getJSDocType(node);
if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) {
const jsDocFunctionType = <JSDocFunctionType>jsdocType;
if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].type.kind === SyntaxKind.JSDocThisType) {
return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
}
@@ -10847,7 +10959,7 @@ namespace ts {
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
if (node === binaryExpression.right) {
return checkExpression(binaryExpression.left);
return getTypeOfExpression(binaryExpression.left);
}
}
else if (operator === SyntaxKind.BarBarToken) {
@@ -10855,7 +10967,7 @@ namespace ts {
// expression has no contextual type, the right operand is contextually typed by the type of the left operand.
let type = getContextualType(binaryExpression);
if (!type && node === binaryExpression.right) {
type = checkExpression(binaryExpression.left);
type = getTypeOfExpression(binaryExpression.left);
}
return type;
}
@@ -11418,7 +11530,7 @@ namespace ts {
typeFlags = 0;
}
const type = checkExpression((memberDecl as SpreadAssignment).expression);
if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) {
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return unknownType;
}
@@ -11496,6 +11608,12 @@ namespace ts {
}
}
function isValidSpreadType(type: Type): boolean {
return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined) ||
type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
type.flags & TypeFlags.UnionOrIntersection && !forEach((<UnionOrIntersectionType>type).types, t => !isValidSpreadType(t)));
}
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
checkJsxOpeningLikeElement(node);
return jsxElementType || anyType;
@@ -12236,7 +12354,7 @@ namespace ts {
if (node.kind === SyntaxKind.ForInStatement &&
child === (<ForInStatement>node).statement &&
getForInVariableSymbol(<ForInStatement>node) === symbol &&
hasNumericPropertyNames(checkExpression((<ForInStatement>node).expression))) {
hasNumericPropertyNames(getTypeOfExpression((<ForInStatement>node).expression))) {
return true;
}
child = node;
@@ -12499,7 +12617,7 @@ namespace ts {
const context = createInferenceContext(signature, /*inferUnionTypes*/ true);
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypes(context, instantiateType(source, contextualMapper), target);
inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
});
return getSignatureInstantiation(signature, getInferredTypes(context));
}
@@ -12534,7 +12652,7 @@ namespace ts {
if (thisType) {
const thisArgumentNode = getThisArgumentOfCall(node);
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
inferTypes(context, thisArgumentType, thisType);
inferTypesWithContext(context, thisArgumentType, thisType);
}
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
@@ -12556,7 +12674,7 @@ namespace ts {
argType = checkExpressionWithContextualType(arg, paramType, mapper);
}
inferTypes(context, argType, paramType);
inferTypesWithContext(context, argType, paramType);
}
}
@@ -12571,7 +12689,7 @@ namespace ts {
if (excludeArgument[i] === false) {
const arg = args[i];
const paramType = getTypeAtPosition(signature, i);
inferTypes(context, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
inferTypesWithContext(context, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
}
}
}
@@ -13662,7 +13780,7 @@ namespace ts {
for (let i = 0; i < len; i++) {
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
if (declaration.type) {
inferTypes(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
inferTypesWithContext(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
}
}
}
@@ -13695,7 +13813,7 @@ namespace ts {
// the destructured type into the contained binding elements.
function assignBindingElementTypes(node: VariableLikeDeclaration) {
if (isBindingPattern(node.name)) {
for (const element of (<BindingPattern>node.name).elements) {
for (const element of node.name.elements) {
if (!isOmittedExpression(element)) {
if (element.name.kind === SyntaxKind.Identifier) {
getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
@@ -13748,7 +13866,7 @@ namespace ts {
// T in the second overload so that we do not infer Base as a candidate for T
// (inferring Base would make type argument inference inconsistent between the two
// overloads).
inferTypes(mapper.context, links.type, instantiateType(contextualType, mapper));
inferTypesWithContext(mapper.context, links.type, instantiateType(contextualType, mapper));
}
}
@@ -13887,7 +14005,7 @@ namespace ts {
if (!node.possiblyExhaustive) {
return false;
}
const type = checkExpression(node.expression);
const type = getTypeOfExpression(node.expression);
if (!isLiteralType(type)) {
return false;
}
@@ -13895,7 +14013,7 @@ namespace ts {
if (!switchTypes.length) {
return false;
}
return eachTypeContainedIn(type, switchTypes);
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
}
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
@@ -14335,10 +14453,10 @@ 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 (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
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.TypeParameter)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
@@ -14954,7 +15072,7 @@ namespace ts {
}
contextualType = apparentType;
}
return maybeTypeOfKind(contextualType, TypeFlags.Literal);
return maybeTypeOfKind(contextualType, (TypeFlags.Literal | TypeFlags.Index));
}
return false;
}
@@ -15007,6 +15125,24 @@ namespace ts {
return type;
}
// Returns the type of an expression. Unlike checkExpression, this function is simply concerned
// with computing the type and may not fully check all contained sub-expressions for errors.
function getTypeOfExpression(node: Expression) {
// 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) {
const funcType = checkNonNullExpression((<CallExpression>node).expression);
const signature = getSingleCallSignature(funcType);
if (signature && !signature.typeParameters) {
return getReturnTypeOfSignature(signature);
}
}
// Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
// should have a parameter that indicates whether full error checking is required such that
// we can perform the optimizations locally.
return checkExpression(node);
}
// Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
// contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
// expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
@@ -15768,7 +15904,7 @@ namespace ts {
const type = <MappedType>getTypeFromMappedTypeNode(node);
const constraintType = getConstraintTypeFromMappedType(type);
const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentTypeOfTypeParameter(<TypeParameter>constraintType) : constraintType;
checkTypeAssignableTo(keyType, stringOrNumberType, node.typeParameter.constraint);
checkTypeAssignableTo(keyType, stringType, node.typeParameter.constraint);
}
function isPrivateWithinAmbient(node: Node): boolean {
@@ -17294,6 +17430,7 @@ namespace ts {
// Grammar checking
checkGrammarForInOrForOfStatement(node);
const rightType = checkNonNullExpression(node.expression);
// TypeScript 1.0 spec (April 2014): 5.4
// In a 'for-in' statement of the form
// for (let VarDecl in Expr) Statement
@@ -17304,7 +17441,6 @@ namespace ts {
if (variable && isBindingPattern(variable.name)) {
error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
checkForInOrForOfVariableDeclaration(node);
}
else {
@@ -17317,7 +17453,7 @@ namespace ts {
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike)) {
else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
}
else {
@@ -17326,10 +17462,9 @@ namespace ts {
}
}
const rightType = checkNonNullExpression(node.expression);
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
@@ -18643,7 +18778,7 @@ namespace ts {
}
}
enumType = checkExpression(expression);
enumType = getTypeOfExpression(expression);
// allow references to constant members of other enums
if (!(enumType.symbol && (enumType.symbol.flags & SymbolFlags.Enum))) {
return undefined;
@@ -19813,7 +19948,7 @@ namespace ts {
// fallthrough
case SyntaxKind.SuperKeyword:
const type = isPartOfExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
const type = isPartOfExpression(node) ? getTypeOfExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
return type.symbol;
case SyntaxKind.ThisType:
@@ -19843,7 +19978,7 @@ namespace ts {
case SyntaxKind.NumericLiteral:
// index access
if (node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).argumentExpression === node) {
const objectType = checkExpression((<ElementAccessExpression>node.parent).expression);
const objectType = getTypeOfExpression((<ElementAccessExpression>node.parent).expression);
if (objectType === unknownType) return undefined;
const apparentType = getApparentType(objectType);
if (apparentType === unknownType) return undefined;
@@ -19882,7 +20017,7 @@ namespace ts {
}
if (isPartOfExpression(node)) {
return getTypeOfExpression(<Expression>node);
return getRegularTypeOfExpression(<Expression>node);
}
if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
@@ -19944,7 +20079,7 @@ namespace ts {
// If this is from "for" initializer
// for ({a } = elems[0];.....) { }
if (expr.parent.kind === SyntaxKind.BinaryExpression) {
const iteratedType = checkExpression((<BinaryExpression>expr.parent).right);
const iteratedType = getTypeOfExpression((<BinaryExpression>expr.parent).right);
return checkDestructuringAssignment(expr, iteratedType || unknownType);
}
// If this is from nested object binding pattern
@@ -19974,11 +20109,11 @@ namespace ts {
return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.text);
}
function getTypeOfExpression(expr: Expression): Type {
function getRegularTypeOfExpression(expr: Expression): Type {
if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
expr = <Expression>expr.parent;
}
return getRegularTypeOfLiteralType(checkExpression(expr));
return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
}
/**
@@ -20405,7 +20540,7 @@ namespace ts {
}
function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
const type = getWidenedType(getTypeOfExpression(expr));
const type = getWidenedType(getRegularTypeOfExpression(expr));
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
}
@@ -21436,6 +21571,9 @@ namespace ts {
else if (accessor.body === undefined && !(getModifierFlags(accessor) & ModifierFlags.Abstract)) {
return grammarErrorAtPos(getSourceFileOfNode(accessor), accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
}
else if (accessor.body && getModifierFlags(accessor) & ModifierFlags.Abstract) {
return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
}
else if (accessor.typeParameters) {
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
}
+39 -13
View File
@@ -472,11 +472,18 @@ namespace ts {
];
/* @internal */
export let typingOptionDeclarations: CommandLineOption[] = [
export let typeAcquisitionDeclarations: CommandLineOption[] = [
{
/* @deprecated typingOptions.enableAutoDiscovery
* Use typeAcquisition.enable instead.
*/
name: "enableAutoDiscovery",
type: "boolean",
},
{
name: "enable",
type: "boolean",
},
{
name: "include",
type: "list",
@@ -511,6 +518,20 @@ namespace ts {
let optionNameMapCache: OptionNameMap;
/* @internal */
export function convertEnableAutoDiscoveryToEnable(typeAcquisition: TypeAcquisition): TypeAcquisition {
// Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
const result: TypeAcquisition = {
enable: typeAcquisition.enableAutoDiscovery,
include: typeAcquisition.include || [],
exclude: typeAcquisition.exclude || []
};
return result;
}
return typeAcquisition;
}
/* @internal */
export function getOptionNameMap(): OptionNameMap {
if (optionNameMapCache) {
@@ -845,7 +866,7 @@ namespace ts {
return {
options: {},
fileNames: [],
typingOptions: {},
typeAcquisition: {},
raw: json,
errors: [createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))],
wildcardDirectories: {}
@@ -853,7 +874,10 @@ namespace ts {
}
let options: CompilerOptions = convertCompilerOptionsFromJsonWorker(json["compilerOptions"], basePath, errors, configFileName);
const typingOptions: TypingOptions = convertTypingOptionsFromJsonWorker(json["typingOptions"], basePath, errors, configFileName);
// typingOptions has been deprecated and is only supported for backward compatibility purposes.
// It should be removed in future releases - use typeAcquisition instead.
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
const typeAcquisition: TypeAcquisition = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
if (json["extends"]) {
let [include, exclude, files, baseOptions]: [string[], string[], string[], CompilerOptions] = [undefined, undefined, undefined, {}];
@@ -884,7 +908,7 @@ namespace ts {
return {
options,
fileNames,
typingOptions,
typeAcquisition,
raw: json,
errors,
wildcardDirectories,
@@ -961,8 +985,8 @@ namespace ts {
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
}
else {
// By default, exclude common package folders and the outDir
excludeSpecs = ["node_modules", "bower_components", "jspm_packages"];
// If no includes were specified, exclude common package folders and the outDir
excludeSpecs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"];
const outDir = json["compilerOptions"] && json["compilerOptions"]["outDir"];
if (outDir) {
@@ -1006,9 +1030,9 @@ namespace ts {
return { options, errors };
}
export function convertTypingOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: TypingOptions, errors: Diagnostic[] } {
export function convertTypeAcquisitionFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: TypeAcquisition, errors: Diagnostic[] } {
const errors: Diagnostic[] = [];
const options = convertTypingOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
const options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
return { options, errors };
}
@@ -1022,16 +1046,18 @@ namespace ts {
return options;
}
function convertTypingOptionsFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypingOptions {
function convertTypeAcquisitionFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypeAcquisition {
const options: TypeAcquisition = { enable: getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
const typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
convertOptionsFromJson(typeAcquisitionDeclarations, typeAcquisition, basePath, options, Diagnostics.Unknown_type_acquisition_option_0, errors);
const options: TypingOptions = { enableAutoDiscovery: getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_typing_option_0, errors);
return options;
}
function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypingOptions, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {
defaultOptions: CompilerOptions | TypeAcquisition, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {
if (!jsonOptions) {
return;
+1 -1
View File
@@ -371,7 +371,7 @@ namespace ts {
function writeJsDocComments(declaration: Node) {
if (declaration) {
const jsDocComments = getJsDocCommentsFromText(declaration, currentText);
const jsDocComments = getJSDocCommentRanges(declaration, currentText);
emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeCommentRange);
+9 -1
View File
@@ -855,6 +855,10 @@
"category": "Error",
"code": 1317
},
"An abstract accessor cannot have an implementation.": {
"category": "Error",
"code": 1318
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
@@ -2027,6 +2031,10 @@
"category": "Error",
"code": 2701
},
"'{0}' only refers to a type, but is being used as a namespace here.": {
"category": "Error",
"code": 2702
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -3177,7 +3185,7 @@
"category": "Error",
"code": 17009
},
"Unknown typing option '{0}'.": {
"Unknown type acquisition option '{0}'.": {
"category": "Error",
"code": 17010
},
+2 -2
View File
@@ -143,7 +143,7 @@ namespace ts {
// Write the source map
if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false);
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
}
// Record source map data for the test harness.
@@ -152,7 +152,7 @@ namespace ts {
}
// Write the output file
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM);
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
// Reset state
sourceMap.reset();
+17 -14
View File
@@ -655,16 +655,16 @@ namespace ts {
if (whenFalse) {
// second overload
node.questionToken = <QuestionToken>questionTokenOrWhenTrue;
node.whenTrue = whenTrueOrWhenFalse;
node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(whenTrueOrWhenFalse);
node.colonToken = <ColonToken>colonTokenOrLocation;
node.whenFalse = whenFalse;
node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenFalse);
}
else {
// first overload
node.questionToken = createToken(SyntaxKind.QuestionToken);
node.whenTrue = <Expression>questionTokenOrWhenTrue;
node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(<Expression>questionTokenOrWhenTrue);
node.colonToken = createToken(SyntaxKind.ColonToken);
node.whenFalse = whenTrueOrWhenFalse;
node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenTrueOrWhenFalse);
}
return node;
}
@@ -1683,16 +1683,10 @@ namespace ts {
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
if (isQualifiedName(jsxFactory)) {
return createPropertyAccess(
createJsxFactoryExpressionFromEntityName(
jsxFactory.left,
parent
),
setEmitFlags(
getMutableClone(jsxFactory.right),
EmitFlags.NoSourceMap
)
);
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
const right = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
right.text = jsxFactory.right.text;
return createPropertyAccess(left, right);
}
else {
return createReactNamespace(jsxFactory.text, parent);
@@ -2547,6 +2541,15 @@ namespace ts {
return condition;
}
function parenthesizeSubexpressionOfConditionalExpression(e: Expression): Expression {
// per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
// so in case when comma expression is introduced as a part of previous transformations
// if should be wrapped in parens since comma operator has the lowest precedence
return e.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>e).operatorToken.kind === SyntaxKind.CommaToken
? createParen(e)
: e;
}
/**
* Wraps an expression in parentheses if it is needed in order to use the expression
* as the expression of a NewExpression node.
+29 -11
View File
@@ -419,6 +419,8 @@ namespace ts {
return visitNode(cbNode, (<JSDocReturnTag>node).typeExpression);
case SyntaxKind.JSDocTypeTag:
return visitNode(cbNode, (<JSDocTypeTag>node).typeExpression);
case SyntaxKind.JSDocAugmentsTag:
return visitNode(cbNode, (<JSDocAugmentsTag>node).typeExpression);
case SyntaxKind.JSDocTemplateTag:
return visitNodes(cbNodes, (<JSDocTemplateTag>node).typeParameters);
case SyntaxKind.JSDocTypedefTag:
@@ -682,7 +684,7 @@ namespace ts {
function addJSDocComment<T extends Node>(node: T): T {
const comments = getJsDocCommentsFromText(node, sourceFile.text);
const comments = getJSDocCommentRanges(node, sourceFile.text);
if (comments) {
for (const comment of comments) {
const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
@@ -690,10 +692,10 @@ namespace ts {
continue;
}
if (!node.jsDocComments) {
node.jsDocComments = [];
if (!node.jsDoc) {
node.jsDoc = [];
}
node.jsDocComments.push(jsDoc);
node.jsDoc.push(jsDoc);
}
}
@@ -720,11 +722,11 @@ namespace ts {
const saveParent = parent;
parent = n;
forEachChild(n, visitNode);
if (n.jsDocComments) {
for (const jsDocComment of n.jsDocComments) {
jsDocComment.parent = n;
parent = jsDocComment;
forEachChild(jsDocComment, visitNode);
if (n.jsDoc) {
for (const jsDoc of n.jsDoc) {
jsDoc.parent = n;
parent = jsDoc;
forEachChild(jsDoc, visitNode);
}
}
parent = saveParent;
@@ -2557,6 +2559,8 @@ namespace ts {
case SyntaxKind.OpenBraceToken:
case SyntaxKind.OpenBracketToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.BarToken:
case SyntaxKind.AmpersandToken:
case SyntaxKind.NewKeyword:
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
@@ -2616,6 +2620,7 @@ namespace ts {
}
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
parseOptional(operator);
let type = parseConstituentType();
if (token() === operator) {
const types = createNodeArray<TypeNode>([type], type.pos);
@@ -6429,6 +6434,9 @@ namespace ts {
let tag: JSDocTag;
if (tagName) {
switch (tagName.text) {
case "augments":
tag = parseAugmentsTag(atToken, tagName);
break;
case "param":
tag = parseParamTag(atToken, tagName);
break;
@@ -6645,6 +6653,16 @@ namespace ts {
return finishNode(result);
}
function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag {
const typeExpression = tryParseTypeExpression();
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
result.typeExpression = typeExpression;
return finishNode(result);
}
function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6957,8 +6975,8 @@ namespace ts {
}
forEachChild(node, visitNode, visitArray);
if (node.jsDocComments) {
for (const jsDocComment of node.jsDocComments) {
if (node.jsDoc) {
for (const jsDocComment of node.jsDoc) {
forEachChild(jsDocComment, visitNode, visitArray);
}
}
+1 -1
View File
@@ -478,7 +478,7 @@ namespace ts {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
+2 -2
View File
@@ -1353,13 +1353,13 @@ namespace ts {
// __metadata("design:type", Function),
// __metadata("design:paramtypes", [Object]),
// __metadata("design:returntype", void 0)
// ], C.prototype, "method", undefined);
// ], C.prototype, "method", null);
//
// The emit for an accessor is:
//
// __decorate([
// dec
// ], C.prototype, "accessor", undefined);
// ], C.prototype, "accessor", null);
//
// The emit for a property is:
//
+1 -61
View File
@@ -43,66 +43,6 @@ namespace ts {
}
}
/**
* Checks to see if the locale is in the appropriate format,
* and if it is, attempts to set the appropriate language.
*/
function validateLocaleAndSetLanguage(locale: string, errors: Diagnostic[]): boolean {
const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
if (!matchResult) {
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
return false;
}
const language = matchResult[1];
const territory = matchResult[3];
// First try the entire locale, then fall back to just language if that's all we have.
// Either ways do not fail, and fallback to the English diagnostic strings.
if (!trySetLanguageAndTerritory(language, territory, errors)) {
trySetLanguageAndTerritory(language, undefined, errors);
}
return true;
}
function trySetLanguageAndTerritory(language: string, territory: string, errors: Diagnostic[]): boolean {
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
const containingDirectoryPath = getDirectoryPath(compilerFilePath);
let filePath = combinePaths(containingDirectoryPath, language);
if (territory) {
filePath = filePath + "-" + territory;
}
filePath = sys.resolvePath(combinePaths(filePath, "diagnosticMessages.generated.json"));
if (!sys.fileExists(filePath)) {
return false;
}
// TODO: Add codePage support for readFile?
let fileContents = "";
try {
fileContents = sys.readFile(filePath);
}
catch (e) {
errors.push(createCompilerDiagnostic(Diagnostics.Unable_to_open_file_0, filePath));
return false;
}
try {
ts.localizedDiagnosticMessages = JSON.parse(fileContents);
}
catch (e) {
errors.push(createCompilerDiagnostic(Diagnostics.Corrupted_locale_file_0, filePath));
return false;
}
return true;
}
function countLines(program: Program): number {
let count = 0;
forEach(program.getSourceFiles(), file => {
@@ -263,7 +203,7 @@ namespace ts {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale"), /* host */ undefined);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
validateLocaleAndSetLanguage(commandLine.options.locale, commandLine.errors);
validateLocaleAndSetLanguage(commandLine.options.locale, sys, commandLine.errors);
}
// If there are any errors due to command line parsing and/or
+16 -5
View File
@@ -349,6 +349,7 @@ namespace ts {
JSDocThisType,
JSDocComment,
JSDocTag,
JSDocAugmentsTag,
JSDocParameterTag,
JSDocReturnTag,
JSDocTypeTag,
@@ -491,7 +492,8 @@ namespace ts {
parent?: Node; // Parent node (initialized by binding)
/* @internal */ original?: Node; // The original node if this is an updated node.
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
/* @internal */ jsDocComments?: JSDoc[]; // JSDoc for the node, if it has any.
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
/* @internal */ jsDocCache?: (JSDoc | JSDocTag)[]; // All JSDoc that applies to the node, including parent docs and @param tags
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
@@ -1990,6 +1992,11 @@ namespace ts {
kind: SyntaxKind.JSDocTag;
}
export interface JSDocAugmentsTag extends JSDocTag {
kind: SyntaxKind.JSDocAugmentsTag;
typeExpression: JSDocTypeExpression;
}
export interface JSDocTemplateTag extends JSDocTag {
kind: SyntaxKind.JSDocTemplateTag;
typeParameters: NodeArray<TypeParameterDeclaration>;
@@ -2791,7 +2798,7 @@ namespace ts {
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never,
/* @internal */
Primitive = String | Number | Boolean | Enum | ESSymbol | Void | Undefined | Null | Literal,
StringLike = String | StringLiteral,
StringLike = String | StringLiteral | Index,
NumberLike = Number | NumberLiteral | Enum | EnumLiteral,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
@@ -3215,8 +3222,12 @@ namespace ts {
[option: string]: CompilerOptionsValue | undefined;
}
export interface TypingOptions {
export interface TypeAcquisition {
/* @deprecated typingOptions.enableAutoDiscovery
* Use typeAcquisition.enable instead.
*/
enableAutoDiscovery?: boolean;
enable?: boolean;
include?: string[];
exclude?: string[];
[option: string]: string[] | boolean | undefined;
@@ -3227,7 +3238,7 @@ namespace ts {
projectRootPath: string; // The path to the project root directory
safeListPath: string; // The path used to retrieve the safe list
packageNameToTypingLocation: Map<string>; // The map of package names to their cached typing locations
typingOptions: TypingOptions; // Used to customize the typing inference process
typeAcquisition: TypeAcquisition; // Used to customize the type acquisition process
compilerOptions: CompilerOptions; // Used as a source for typing inference
unresolvedImports: ReadonlyArray<string>; // List of unresolved module ids from imports
}
@@ -3292,7 +3303,7 @@ namespace ts {
/** Either a parsed command line or a parsed tsconfig.json */
export interface ParsedCommandLine {
options: CompilerOptions;
typingOptions?: TypingOptions;
typeAcquisition?: TypeAcquisition;
fileNames: string[];
raw?: any;
errors: Diagnostic[];
+159 -144
View File
@@ -239,7 +239,7 @@ namespace ts {
return !nodeIsMissing(node);
}
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, includeJsDocComment?: boolean): number {
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, includeJsDoc?: boolean): number {
// With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
// want to skip trivia because this will launch us forward to the next token.
if (nodeIsMissing(node)) {
@@ -250,8 +250,8 @@ namespace ts {
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
}
if (includeJsDocComment && node.jsDocComments && node.jsDocComments.length > 0) {
return getTokenPosOfNode(node.jsDocComments[0]);
if (includeJsDoc && node.jsDoc && node.jsDoc.length > 0) {
return getTokenPosOfNode(node.jsDoc[0]);
}
// For a syntax list, it is possible that one of its children has JSDocComment nodes, while
@@ -259,7 +259,7 @@ namespace ts {
// trivia for the list, we may have skipped the JSDocComment as well. So we should process its
// first child to determine the actual position of its first token.
if (node.kind === SyntaxKind.SyntaxList && (<SyntaxList>node)._children.length > 0) {
return getTokenPosOfNode((<SyntaxList>node)._children[0], sourceFile, includeJsDocComment);
return getTokenPosOfNode((<SyntaxList>node)._children[0], sourceFile, includeJsDoc);
}
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
@@ -476,15 +476,15 @@ namespace ts {
export function getTextOfPropertyName(name: PropertyName): string {
switch (name.kind) {
case SyntaxKind.Identifier:
return (<Identifier>name).text;
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
return (<LiteralExpression>name).text;
case SyntaxKind.ComputedPropertyName:
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression)) {
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
}
case SyntaxKind.Identifier:
return (<Identifier>name).text;
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
return (<LiteralExpression>name).text;
case SyntaxKind.ComputedPropertyName:
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression)) {
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
}
}
return undefined;
@@ -628,25 +628,18 @@ namespace ts {
return getLeadingCommentRanges(text, node.pos);
}
export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) {
return getJsDocCommentsFromText(node, sourceFileOfNode.text);
}
export function getJsDocCommentsFromText(node: Node, text: string) {
export function getJSDocCommentRanges(node: Node, text: string) {
const commentRanges = (node.kind === SyntaxKind.Parameter ||
node.kind === SyntaxKind.TypeParameter ||
node.kind === SyntaxKind.FunctionExpression ||
node.kind === SyntaxKind.ArrowFunction) ?
concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) :
getLeadingCommentRangesOfNodeFromText(node, text);
return filter(commentRanges, isJsDocComment);
function isJsDocComment(comment: CommentRange) {
// True if the comment starts with '/**' but not if it is '/**/'
return text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 2) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash;
}
// True if the comment starts with '/**' but not if it is '/**/'
return filter(commentRanges, comment =>
text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 2) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash);
}
export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
@@ -1440,57 +1433,42 @@ namespace ts {
(<JSDocFunctionType>node).parameters[0].type.kind === SyntaxKind.JSDocConstructorType;
}
function getJSDocTag(node: Node, kind: SyntaxKind, checkParentVariableStatement: boolean): JSDocTag {
if (!node) {
return undefined;
}
const jsDocTags = getJSDocTags(node, checkParentVariableStatement);
if (!jsDocTags) {
return undefined;
}
for (const tag of jsDocTags) {
if (tag.kind === kind) {
return tag;
}
}
export function getCommentsFromJSDoc(node: Node): string[] {
return map(getJSDocs(node), doc => doc.comment);
}
function append<T>(previous: T[] | undefined, additional: T[] | undefined): T[] | undefined {
if (additional) {
if (!previous) {
previous = [];
}
for (const x of additional) {
previous.push(x);
}
}
return previous;
}
export function getJSDocComments(node: Node, checkParentVariableStatement: boolean): string[] {
return getJSDocs(node, checkParentVariableStatement, docs => map(docs, doc => doc.comment), tags => map(tags, tag => tag.comment));
}
function getJSDocTags(node: Node, checkParentVariableStatement: boolean): JSDocTag[] {
return getJSDocs(node, checkParentVariableStatement, docs => {
function getJSDocTags(node: Node, kind: SyntaxKind): JSDocTag[] {
const docs = getJSDocs(node);
if (docs) {
const result: JSDocTag[] = [];
for (const doc of docs) {
if (doc.tags) {
result.push(...doc.tags);
if (doc.kind === SyntaxKind.JSDocParameterTag) {
if (doc.kind === kind) {
result.push(doc as JSDocTag);
}
}
else {
result.push(...filter((doc as JSDoc).tags, tag => tag.kind === kind));
}
}
return result;
}, tags => tags);
}
}
function getJSDocs<T>(node: Node, checkParentVariableStatement: boolean, getDocs: (docs: JSDoc[]) => T[], getTags: (tags: JSDocTag[]) => T[]): T[] {
// TODO: Get rid of getJsDocComments and friends (note the lowercase 's' in Js)
// TODO: A lot of this work should be cached, maybe. I guess it's only used in services right now...
let result: T[] = undefined;
// prepend documentation from parent sources
if (checkParentVariableStatement) {
function getFirstJSDocTag(node: Node, kind: SyntaxKind): JSDocTag {
return node && firstOrUndefined(getJSDocTags(node, kind));
}
function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
let cache: (JSDoc | JSDocTag)[] = node.jsDocCache;
if (!cache) {
getJSDocsWorker(node);
node.jsDocCache = cache;
}
return cache;
function getJSDocsWorker(node: Node) {
const parent = node.parent;
// Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
// /**
// * @param {number} name
@@ -1498,68 +1476,55 @@ namespace ts {
// */
// var x = function(name) { return name.length; }
const isInitializerOfVariableDeclarationInStatement =
isVariableLike(node.parent) &&
(node.parent).initializer === node &&
node.parent.parent.parent.kind === SyntaxKind.VariableStatement;
isVariableLike(parent) &&
parent.initializer === node &&
parent.parent.parent.kind === SyntaxKind.VariableStatement;
const isVariableOfVariableDeclarationStatement = isVariableLike(node) &&
node.parent.parent.kind === SyntaxKind.VariableStatement;
parent.parent.kind === SyntaxKind.VariableStatement;
const variableStatementNode =
isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent :
isVariableOfVariableDeclarationStatement ? node.parent.parent :
undefined;
isInitializerOfVariableDeclarationInStatement ? parent.parent.parent :
isVariableOfVariableDeclarationStatement ? parent.parent :
undefined;
if (variableStatementNode) {
result = append(result, getJSDocs(variableStatementNode, checkParentVariableStatement, getDocs, getTags));
}
if (node.kind === SyntaxKind.ModuleDeclaration &&
node.parent && node.parent.kind === SyntaxKind.ModuleDeclaration) {
result = append(result, getJSDocs(node.parent, checkParentVariableStatement, getDocs, getTags));
getJSDocsWorker(variableStatementNode);
}
// Also recognize when the node is the RHS of an assignment expression
const parent = node.parent;
const isSourceOfAssignmentExpressionStatement =
parent && parent.parent &&
parent.kind === SyntaxKind.BinaryExpression &&
(parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken &&
parent.parent.kind === SyntaxKind.ExpressionStatement;
if (isSourceOfAssignmentExpressionStatement) {
result = append(result, getJSDocs(parent.parent, checkParentVariableStatement, getDocs, getTags));
getJSDocsWorker(parent.parent);
}
const isModuleDeclaration = node.kind === SyntaxKind.ModuleDeclaration &&
parent && parent.kind === SyntaxKind.ModuleDeclaration;
const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment;
if (isPropertyAssignmentExpression) {
result = append(result, getJSDocs(parent, checkParentVariableStatement, getDocs, getTags));
if (isModuleDeclaration || isPropertyAssignmentExpression) {
getJSDocsWorker(parent);
}
// Pull parameter comments from declaring function as well
if (node.kind === SyntaxKind.Parameter) {
const paramTags = getJSDocParameterTag(node as ParameterDeclaration, checkParentVariableStatement);
if (paramTags) {
result = append(result, getTags(paramTags));
}
cache = concatenate(cache, getJSDocParameterTags(node));
}
}
if (isVariableLike(node) && node.initializer) {
result = append(result, getJSDocs(node.initializer, /*checkParentVariableStatement*/ false, getDocs, getTags));
}
if (node.jsDocComments) {
if (result) {
result = append(result, getDocs(node.jsDocComments));
if (isVariableLike(node) && node.initializer) {
cache = concatenate(cache, node.initializer.jsDoc);
}
else {
return getDocs(node.jsDocComments);
}
}
return result;
cache = concatenate(cache, node.jsDoc);
}
}
function getJSDocParameterTag(param: ParameterDeclaration, checkParentVariableStatement: boolean): JSDocTag[] {
export function getJSDocParameterTags(param: Node): JSDocParameterTag[] {
if (!isParameter(param)) {
return undefined;
}
const func = param.parent as FunctionLikeDeclaration;
const tags = getJSDocTags(func, checkParentVariableStatement);
const tags = getJSDocTags(func, SyntaxKind.JSDocParameterTag) as JSDocParameterTag[];
if (!param.name) {
// this is an anonymous jsdoc param from a `function(type1, type2): type3` specification
const i = func.parameters.indexOf(param);
@@ -1570,10 +1535,7 @@ namespace ts {
}
else if (param.name.kind === SyntaxKind.Identifier) {
const name = (param.name as Identifier).text;
const paramTags = filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && (tag as JSDocParameterTag).parameterName.text === name);
if (paramTags) {
return paramTags;
}
return filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && tag.parameterName.text === name);
}
else {
// TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines
@@ -1582,39 +1544,28 @@ namespace ts {
}
}
export function getJSDocTypeTag(node: Node): JSDocTypeTag {
return <JSDocTypeTag>getJSDocTag(node, SyntaxKind.JSDocTypeTag, /*checkParentVariableStatement*/ false);
}
export function getJSDocReturnTag(node: Node): JSDocReturnTag {
return <JSDocReturnTag>getJSDocTag(node, SyntaxKind.JSDocReturnTag, /*checkParentVariableStatement*/ true);
}
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
return <JSDocTemplateTag>getJSDocTag(node, SyntaxKind.JSDocTemplateTag, /*checkParentVariableStatement*/ false);
}
export function getCorrespondingJSDocParameterTag(parameter: ParameterDeclaration): JSDocParameterTag {
if (parameter.name && parameter.name.kind === SyntaxKind.Identifier) {
// If it's a parameter, see if the parent has a jsdoc comment with an @param
// annotation.
const parameterName = (<Identifier>parameter.name).text;
const jsDocTags = getJSDocTags(parameter.parent, /*checkParentVariableStatement*/ true);
if (!jsDocTags) {
return undefined;
}
for (const tag of jsDocTags) {
if (tag.kind === SyntaxKind.JSDocParameterTag) {
const parameterTag = <JSDocParameterTag>tag;
if (parameterTag.parameterName.text === parameterName) {
return parameterTag;
}
}
export function getJSDocType(node: Node): JSDocType {
let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
if (!tag && node.kind === SyntaxKind.Parameter) {
const paramTags = getJSDocParameterTags(node);
if (paramTags) {
tag = find(paramTags, tag => !!tag.typeExpression);
}
}
return undefined;
return tag && tag.typeExpression && tag.typeExpression.type;
}
export function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag {
return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsTag) as JSDocAugmentsTag;
}
export function getJSDocReturnTag(node: Node): JSDocReturnTag {
return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag;
}
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
}
export function hasRestParameter(s: SignatureDeclaration): boolean {
@@ -1627,14 +1578,11 @@ namespace ts {
export function isRestParameter(node: ParameterDeclaration) {
if (node && (node.flags & NodeFlags.JavaScriptFile)) {
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType ||
forEach(getJSDocParameterTags(node),
t => t.typeExpression && t.typeExpression.type.kind === SyntaxKind.JSDocVariadicType)) {
return true;
}
const paramTag = getCorrespondingJSDocParameterTag(node);
if (paramTag && paramTag.typeExpression) {
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
}
}
return isDeclaredRestParam(node);
}
@@ -4613,4 +4561,71 @@ namespace ts {
return flags;
}
/**
* Checks to see if the locale is in the appropriate format,
* and if it is, attempts to set the appropriate language.
*/
export function validateLocaleAndSetLanguage(
locale: string,
sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string },
errors?: Diagnostic[]) {
const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
if (!matchResult) {
if (errors) {
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
}
return;
}
const language = matchResult[1];
const territory = matchResult[3];
// First try the entire locale, then fall back to just language if that's all we have.
// Either ways do not fail, and fallback to the English diagnostic strings.
if (!trySetLanguageAndTerritory(language, territory, errors)) {
trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
}
function trySetLanguageAndTerritory(language: string, territory: string, errors?: Diagnostic[]): boolean {
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
const containingDirectoryPath = getDirectoryPath(compilerFilePath);
let filePath = combinePaths(containingDirectoryPath, language);
if (territory) {
filePath = filePath + "-" + territory;
}
filePath = sys.resolvePath(combinePaths(filePath, "diagnosticMessages.generated.json"));
if (!sys.fileExists(filePath)) {
return false;
}
// TODO: Add codePage support for readFile?
let fileContents = "";
try {
fileContents = sys.readFile(filePath);
}
catch (e) {
if (errors) {
errors.push(createCompilerDiagnostic(Diagnostics.Unable_to_open_file_0, filePath));
}
return false;
}
try {
ts.localizedDiagnosticMessages = JSON.parse(fileContents);
}
catch (e) {
if (errors) {
errors.push(createCompilerDiagnostic(Diagnostics.Corrupted_locale_file_0, filePath));
}
return false;
}
return true;
}
}
}
+1 -1
View File
@@ -2015,7 +2015,7 @@ namespace Harness {
export function isDefaultLibraryFile(filePath: string): boolean {
// We need to make sure that the filePath is prefixed with "lib." not just containing "lib." and end with ".d.ts"
const fileName = ts.getBaseFileName(filePath);
const fileName = ts.getBaseFileName(ts.normalizeSlashes(filePath));
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ".d.ts");
}
+1 -1
View File
@@ -199,7 +199,7 @@ namespace RWC {
}
// Do not include the library in the baselines to avoid noise
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
const errors = compilerResult.errors.filter(e => !Harness.isDefaultLibraryFile(e.file.fileName));
const errors = compilerResult.errors.filter(e => e.file && !Harness.isDefaultLibraryFile(e.file.fileName));
return Harness.Compiler.getErrorBaseline(baselineFiles, errors);
}, baselineOpts);
});
+1 -1
View File
@@ -108,7 +108,7 @@
"./unittests/commandLineParsing.ts",
"./unittests/configurationExtension.ts",
"./unittests/convertCompilerOptionsFromJson.ts",
"./unittests/convertTypingOptionsFromJson.ts",
"./unittests/convertTypeAcquisitionFromJson.ts",
"./unittests/tsserverProjectSystem.ts",
"./unittests/matchFiles.ts",
"./unittests/initializeTSConfig.ts",
@@ -2,12 +2,13 @@
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
describe("convertTypingOptionsFromJson", () => {
function assertTypingOptions(json: any, configFileName: string, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) {
const { options: actualTypingOptions, errors: actualErrors } = convertTypingOptionsFromJson(json["typingOptions"], "/apath/", configFileName);
const parsedTypingOptions = JSON.stringify(actualTypingOptions);
const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions);
assert.equal(parsedTypingOptions, expectedTypingOptions);
describe("convertTypeAcquisitionFromJson", () => {
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: { typeAcquisition: TypeAcquisition, errors: Diagnostic[] }) {
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
const parsedTypeAcquisition = JSON.stringify(actualTypeAcquisition);
const expectedTypeAcquisition = JSON.stringify(expectedResult.typeAcquisition);
assert.equal(parsedTypeAcquisition, expectedTypeAcquisition);
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
@@ -20,8 +21,8 @@ namespace ts {
}
// tsconfig.json
it("Convert correctly format tsconfig.json to typing-options ", () => {
assertTypingOptions(
it("Convert deprecated typingOptions.enableAutoDiscovery format tsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
{
@@ -32,9 +33,9 @@ namespace ts {
},
"tsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: true,
enable: true,
include: ["0.d.ts", "1.d.ts"],
exclude: ["0.js", "1.js"]
},
@@ -42,25 +43,47 @@ namespace ts {
});
});
it("Convert incorrect format tsconfig.json to typing-options ", () => {
assertTypingOptions(
it("Convert correctly format tsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
"typeAcquisition":
{
"enable": true,
"include": ["0.d.ts", "1.d.ts"],
"exclude": ["0.js", "1.js"]
}
},
"tsconfig.json",
{
typeAcquisition:
{
enable: true,
include: ["0.d.ts", "1.d.ts"],
exclude: ["0.js", "1.js"]
},
errors: <Diagnostic[]>[]
});
});
it("Convert incorrect format tsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typeAcquisition":
{
"enableAutoDiscovy": true,
}
}, "tsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: false,
enable: false,
include: [],
exclude: []
},
errors: [
{
category: Diagnostics.Unknown_typing_option_0.category,
code: Diagnostics.Unknown_typing_option_0.code,
category: Diagnostics.Unknown_type_acquisition_option_0.category,
code: Diagnostics.Unknown_type_acquisition_option_0.code,
file: undefined,
start: 0,
length: 0,
@@ -70,12 +93,12 @@ namespace ts {
});
});
it("Convert default tsconfig.json to typing-options ", () => {
assertTypingOptions({}, "tsconfig.json",
it("Convert default tsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition({}, "tsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: false,
enable: false,
include: [],
exclude: []
},
@@ -83,18 +106,18 @@ namespace ts {
});
});
it("Convert tsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
assertTypingOptions(
it("Convert tsconfig.json with only enable property to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
"typeAcquisition":
{
"enableAutoDiscovery": true
"enable": true
}
}, "tsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: true,
enable: true,
include: [],
exclude: []
},
@@ -103,20 +126,20 @@ namespace ts {
});
// jsconfig.json
it("Convert jsconfig.json to typing-options ", () => {
assertTypingOptions(
it("Convert jsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
"typeAcquisition":
{
"enableAutoDiscovery": false,
"enable": false,
"include": ["0.d.ts"],
"exclude": ["0.js"]
}
}, "jsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: false,
enable: false,
include: ["0.d.ts"],
exclude: ["0.js"]
},
@@ -124,12 +147,12 @@ namespace ts {
});
});
it("Convert default jsconfig.json to typing-options ", () => {
assertTypingOptions({ }, "jsconfig.json",
it("Convert default jsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition({ }, "jsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: true,
enable: true,
include: [],
exclude: []
},
@@ -137,25 +160,25 @@ namespace ts {
});
});
it("Convert incorrect format jsconfig.json to typing-options ", () => {
assertTypingOptions(
it("Convert incorrect format jsconfig.json to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
"typeAcquisition":
{
"enableAutoDiscovy": true,
}
}, "jsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: true,
enable: true,
include: [],
exclude: []
},
errors: [
{
category: Diagnostics.Unknown_compiler_option_0.category,
code: Diagnostics.Unknown_typing_option_0.code,
code: Diagnostics.Unknown_type_acquisition_option_0.code,
file: undefined,
start: 0,
length: 0,
@@ -165,18 +188,18 @@ namespace ts {
});
});
it("Convert jsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
assertTypingOptions(
it("Convert jsconfig.json with only enable property to typeAcquisition ", () => {
assertTypeAcquisition(
{
"typingOptions":
"typeAcquisition":
{
"enableAutoDiscovery": false
"enable": false
}
}, "jsconfig.json",
{
typingOptions:
typeAcquisition:
{
enableAutoDiscovery: false,
enable: false,
include: [],
exclude: []
},
+34 -14
View File
@@ -89,8 +89,6 @@ namespace ts {
"c:/dev/g.min.js/.g/g.ts"
]);
const defaultExcludes = ["node_modules", "bower_components", "jspm_packages"];
function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void {
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
@@ -98,6 +96,23 @@ namespace ts {
}
describe("matchFiles", () => {
it("with defaults", () => {
const json = {};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.ts"
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
describe("with literal file list", () => {
it("without exclusions", () => {
const json = {
@@ -192,7 +207,7 @@ namespace ts {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {},
@@ -211,7 +226,7 @@ namespace ts {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {},
@@ -330,7 +345,10 @@ namespace ts {
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.ts"
"c:/dev/b.ts",
"c:/dev/bower_components/a.ts",
"c:/dev/jspm_packages/a.ts",
"c:/dev/node_modules/a.ts"
],
wildcardDirectories: {},
};
@@ -372,8 +390,7 @@ namespace ts {
"node_modules/a.ts",
"bower_components/a.ts",
"jspm_packages/a.ts"
],
exclude: <string[]>[]
]
};
const expected: ts.ParsedCommandLine = {
options: {},
@@ -530,7 +547,7 @@ namespace ts {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {
@@ -600,7 +617,10 @@ namespace ts {
options: {},
errors: [],
fileNames: [
"c:/dev/a.ts"
"c:/dev/a.ts",
"c:/dev/bower_components/a.ts",
"c:/dev/jspm_packages/a.ts",
"c:/dev/node_modules/a.ts"
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
@@ -671,7 +691,7 @@ namespace ts {
},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {
@@ -980,7 +1000,7 @@ namespace ts {
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {}
@@ -1022,7 +1042,7 @@ namespace ts {
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {}
@@ -1071,7 +1091,7 @@ namespace ts {
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {}
@@ -1091,7 +1111,7 @@ namespace ts {
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
],
fileNames: [],
wildcardDirectories: {}
+71 -6
View File
@@ -51,9 +51,8 @@ namespace ts.projectSystem {
throttleLimit: number,
installTypingHost: server.ServerHost,
readonly typesRegistry = createMap<void>(),
telemetryEnabled?: boolean,
log?: TI.Log) {
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, telemetryEnabled, log);
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, log);
}
safeFileList = safeList.path;
@@ -90,8 +89,8 @@ namespace ts.projectSystem {
this.projectService.updateTypingsForProject(response);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
const request = server.createInstallTypingsRequest(project, typingOptions, unresolvedImports, this.globalTypingsCacheLocation);
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
const request = server.createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, this.globalTypingsCacheLocation);
this.install(request);
}
@@ -578,6 +577,35 @@ namespace ts.projectSystem {
checkWatchedDirectories(host, ["/a/b/c", "/a/b", "/a"]);
});
it("can handle tsconfig file name with difference casing", () => {
const f1 = {
path: "/a/b/app.ts",
content: "let x = 1"
};
const config = {
path: "/a/b/tsconfig.json",
content: JSON.stringify({
include: []
})
};
const host = createServerHost([f1, config], { useCaseSensitiveFileNames: false });
const service = createProjectService(host);
service.openExternalProject(<protocol.ExternalProject>{
projectFileName: "/a/b/project.csproj",
rootFiles: toExternalFiles([f1.path, combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path))]),
options: {}
});
service.checkNumberOfProjects({ configuredProjects: 1 });
checkProjectActualFiles(service.configuredProjects[0], []);
service.openClientFile(f1.path);
service.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 });
checkProjectActualFiles(service.configuredProjects[0], []);
checkProjectActualFiles(service.inferredProjects[0], [f1.path]);
})
it("create configured project without file list", () => {
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",
@@ -1726,8 +1754,8 @@ namespace ts.projectSystem {
options: {}
});
projectService.checkNumberOfProjects({ externalProjects: 1 });
const typingOptions = projectService.externalProjects[0].getTypingOptions();
assert.isTrue(typingOptions.enableAutoDiscovery, "Typing autodiscovery should be enabled");
const typeAcquisition = projectService.externalProjects[0].getTypeAcquisition();
assert.isTrue(typeAcquisition.enable, "Typine acquisition should be enabled");
});
});
@@ -2452,6 +2480,43 @@ namespace ts.projectSystem {
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
});
it("are generated when the config file changes", () => {
const serverEventManager = new TestServerEventManager();
const file = {
path: "/a/b/app.ts",
content: "let x = 10"
};
const configFile = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {}
}`
};
const host = createServerHost([file, configFile]);
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
configFile.content = `{
"compilerOptions": {
"haha": 123
}
}`;
host.reloadFS([file, configFile]);
host.triggerFileWatcherCallback(configFile.path);
host.runQueuedTimeoutCallbacks();
serverEventManager.checkEventCountOfType("configFileDiag", 2);
configFile.content = `{
"compilerOptions": {}
}`;
host.reloadFS([file, configFile]);
host.triggerFileWatcherCallback(configFile.path);
host.runQueuedTimeoutCallbacks();
serverEventManager.checkEventCountOfType("configFileDiag", 3);
});
});
describe("skipLibCheck", () => {
+133 -33
View File
@@ -20,13 +20,12 @@ namespace ts.projectSystem {
}
class Installer extends TestTypingsInstaller {
constructor(host: server.ServerHost, p?: InstallerParams, telemetryEnabled?: boolean, log?: TI.Log) {
constructor(host: server.ServerHost, p?: InstallerParams, log?: TI.Log) {
super(
(p && p.globalTypingsCacheLocation) || "/a/data",
(p && p.throttleLimit) || 5,
host,
(p && p.typesRegistry),
telemetryEnabled,
log);
}
@@ -36,7 +35,7 @@ namespace ts.projectSystem {
}
}
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[], typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
self.addPostExecAction(installedTypings, success => {
for (const file of typingFiles) {
host.createFileOrFolder(file, /*createParentDirectory*/ true);
@@ -57,8 +56,8 @@ namespace ts.projectSystem {
compilerOptions: {
allowJs: true
},
typingOptions: {
enableAutoDiscovery: true
typeAcquisition: {
enable: true
}
})
};
@@ -145,7 +144,7 @@ namespace ts.projectSystem {
checkProjectActualFiles(p, [file1.path, jquery.path]);
});
it("external project - no typing options, no .d.ts/js files", () => {
it("external project - no type acquisition, no .d.ts/js files", () => {
const file1 = {
path: "/a/b/app.ts",
content: ""
@@ -173,7 +172,7 @@ namespace ts.projectSystem {
projectService.checkNumberOfProjects({ externalProjects: 1 });
});
it("external project - no autoDiscovery in typing options, no .d.ts/js files", () => {
it("external project - no auto in typing acquisition, no .d.ts/js files", () => {
const file1 = {
path: "/a/b/app.ts",
content: ""
@@ -194,11 +193,11 @@ namespace ts.projectSystem {
projectFileName,
options: {},
rootFiles: [toExternalFile(file1.path)],
typingOptions: { include: ["jquery"] }
typeAcquisition: { include: ["jquery"] }
});
installer.checkPendingCommands(/*expectedCount*/ 0);
// by default auto discovery will kick in if project contain only .js/.d.ts files
// in this case project contain only ts files - no auto discovery even if typing options is set
// in this case project contain only ts files - no auto discovery even if type acquisition is set
projectService.checkNumberOfProjects({ externalProjects: 1 });
});
@@ -217,9 +216,9 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/node"];
@@ -234,17 +233,17 @@ namespace ts.projectSystem {
projectFileName,
options: {},
rootFiles: [toExternalFile(file1.path)],
typingOptions: { enableAutoDiscovery: true, include: ["jquery"] }
typeAcquisition: { enable: true, include: ["jquery"] }
});
assert.isTrue(enqueueIsCalled, "expected enqueueIsCalled to be true");
installer.installAll(/*expectedCount*/ 1);
// autoDiscovery is set in typing options - use it even if project contains only .ts files
// auto is set in type acquisition - use it even if project contains only .ts files
projectService.checkNumberOfProjects({ externalProjects: 1 });
});
it("external project - no typing options, with only js, jsx, d.ts files", () => {
it("external project - no type acquisition, with only js, jsx, d.ts files", () => {
// Tests:
// 1. react typings are installed for .jsx
// 2. loose files names are matched against safe list for typings if
@@ -288,7 +287,7 @@ namespace ts.projectSystem {
projectFileName,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(file1.path), toExternalFile(file2.path), toExternalFile(file3.path)],
typingOptions: {}
typeAcquisition: {}
});
const p = projectService.externalProjects[0];
@@ -301,7 +300,7 @@ namespace ts.projectSystem {
checkProjectActualFiles(p, [file1.path, file2.path, file3.path, lodash.path, react.path]);
});
it("external project - no typing options, with js & ts files", () => {
it("external project - no type acquisition, with js & ts files", () => {
// Tests:
// 1. No typings are included for JS projects when the project contains ts files
const file1 = {
@@ -319,9 +318,9 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings: string[] = [];
@@ -336,7 +335,7 @@ namespace ts.projectSystem {
projectFileName,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(file1.path), toExternalFile(file2.path)],
typingOptions: {}
typeAcquisition: {}
});
const p = projectService.externalProjects[0];
@@ -349,11 +348,11 @@ namespace ts.projectSystem {
checkProjectActualFiles(p, [file1.path, file2.path]);
});
it("external project - with typing options, with only js, d.ts files", () => {
it("external project - with type acquisition, with only js, d.ts files", () => {
// Tests:
// 1. Safelist matching, typing options includes/excludes and package.json typings are all acquired
// 2. Types for safelist matches are not included when they also appear in the typing option exclude list
// 3. Multiple includes and excludes are respected in typing options
// 1. Safelist matching, type acquisition includes/excludes and package.json typings are all acquired
// 2. Types for safelist matches are not included when they also appear in the type acquisition exclude list
// 3. Multiple includes and excludes are respected in type acquisition
const file1 = {
path: "/a/b/lodash.js",
content: ""
@@ -411,7 +410,7 @@ namespace ts.projectSystem {
projectFileName,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(file1.path), toExternalFile(file2.path), toExternalFile(file3.path)],
typingOptions: { include: ["jquery", "moment"], exclude: ["lodash"] }
typeAcquisition: { include: ["jquery", "moment"], exclude: ["lodash"] }
});
const p = projectService.externalProjects[0];
@@ -486,7 +485,7 @@ namespace ts.projectSystem {
projectFileName,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(lodashJs.path), toExternalFile(commanderJs.path), toExternalFile(file3.path)],
typingOptions: { include: ["jquery", "moment"] }
typeAcquisition: { include: ["jquery", "moment"] }
});
const p = projectService.externalProjects[0];
@@ -572,7 +571,7 @@ namespace ts.projectSystem {
projectFileName: projectFileName1,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(lodashJs.path), toExternalFile(commanderJs.path), toExternalFile(file3.path)],
typingOptions: { include: ["jquery", "cordova"] }
typeAcquisition: { include: ["jquery", "cordova"] }
});
installer.checkPendingCommands(/*expectedCount*/ 1);
@@ -584,7 +583,7 @@ namespace ts.projectSystem {
projectFileName: projectFileName2,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(file3.path)],
typingOptions: { include: ["grunt", "gulp"] }
typeAcquisition: { include: ["grunt", "gulp"] }
});
assert.equal(installer.pendingRunRequests.length, 1, "expect one throttled request");
@@ -907,7 +906,7 @@ namespace ts.projectSystem {
const host = createServerHost([f1, packageJson]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" }, /*telemetryEnabled*/ false, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
}
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
assert(false, "runCommand should not be invoked");
@@ -930,7 +929,7 @@ namespace ts.projectSystem {
const host = createServerHost([f]);
const cache = createMap<string>();
for (const name of JsTyping.nodeCoreModuleList) {
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, [name, "somename"]);
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enable: true }, [name, "somename"]);
assert.deepEqual(result.newTypingNames.sort(), ["node", "somename"]);
}
});
@@ -946,7 +945,7 @@ namespace ts.projectSystem {
};
const host = createServerHost([f, node]);
const cache = createMap<string>({ "node": node.path });
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, ["fs", "bar"]);
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enable: true }, ["fs", "bar"]);
assert.deepEqual(result.cachedTypingPaths, [node.path]);
assert.deepEqual(result.newTypingNames, ["bar"]);
});
@@ -971,15 +970,18 @@ namespace ts.projectSystem {
let seenTelemetryEvent = false;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") }, /*telemetryEnabled*/ true);
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.TypingsInstallEvent) {
if (response.kind === server.EventInstall) {
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
return;
}
if (response.kind === server.EventEndInstallTypes) {
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
seenTelemetryEvent = true;
return;
@@ -997,4 +999,102 @@ namespace ts.projectSystem {
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
});
});
describe("progress notifications", () => {
it ("should be sent for success", () => {
const f1 = {
path: "/a/app.js",
content: ""
};
const package = {
path: "/a/package.json",
content: JSON.stringify({ dependencies: { "commander": "1.0.0" } })
};
const cachePath = "/a/cache/";
const commander = {
path: cachePath + "node_modules/@types/commander/index.d.ts",
content: "export let x: number"
};
const host = createServerHost([f1, package]);
let beginEvent: server.BeginInstallTypes;
let endEvent: server.EndInstallTypes;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
beginEvent = response;
return;
}
if (response.kind === server.EventEndInstallTypes) {
endEvent = response;
return;
}
super.sendResponse(response);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert.isTrue(endEvent.installSuccess);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
});
it ("should be sent for error", () => {
const f1 = {
path: "/a/app.js",
content: ""
};
const package = {
path: "/a/package.json",
content: JSON.stringify({ dependencies: { "commander": "1.0.0" } })
};
const cachePath = "/a/cache/";
const host = createServerHost([f1, package]);
let beginEvent: server.BeginInstallTypes;
let endEvent: server.EndInstallTypes;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeCommand(this, host, "", [], cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
beginEvent = response;
return;
}
if (response.kind === server.EventEndInstallTypes) {
endEvent = response;
return;
}
super.sendResponse(response);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert.isFalse(endEvent.installSuccess);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]);
});
});
}
+1687 -2599
View File
File diff suppressed because it is too large Load Diff
+12 -1
View File
@@ -4,11 +4,22 @@ interface ObjectConstructor {
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values<T>(o: { [s: string]: T }): T[];
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values(o: any): any[];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T }): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T extends { [key: string]: any }, K extends keyof T>(o: T): [keyof T, T[K]][];
entries(o: any): [string, any][];
}
+13 -1
View File
@@ -176,6 +176,18 @@ interface ObjectConstructor {
*/
seal<T>(o: T): T;
/**
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
* @param o Object on which to lock the attributes.
*/
freeze<T>(a: T[]): ReadonlyArray<T>;
/**
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
* @param o Object on which to lock the attributes.
*/
freeze<T extends Function>(f: T): T;
/**
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
* @param o Object on which to lock the attributes.
@@ -1367,7 +1379,7 @@ type Pick<T, K extends keyof T> = {
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends string | number, T> = {
type Record<K extends string, T> = {
[P in K]: T;
}
+131 -83
View File
@@ -8,6 +8,7 @@ interface Algorithm {
}
interface EventInit {
scoped?: boolean;
bubbles?: boolean;
cancelable?: boolean;
}
@@ -242,10 +243,12 @@ interface Event {
readonly target: EventTarget;
readonly timeStamp: number;
readonly type: string;
readonly scoped: boolean;
initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void;
preventDefault(): void;
stopImmediatePropagation(): void;
stopPropagation(): void;
deepPath(): EventTarget[];
readonly AT_TARGET: number;
readonly BUBBLING_PHASE: number;
readonly CAPTURING_PHASE: number;
@@ -298,6 +301,7 @@ interface FileReader extends EventTarget, MSBaseReader {
readAsBinaryString(blob: Blob): void;
readAsDataURL(blob: Blob): void;
readAsText(blob: Blob, encoding?: string): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -339,11 +343,16 @@ declare var IDBCursorWithValue: {
new(): IDBCursorWithValue;
}
interface IDBDatabaseEventMap {
"abort": Event;
"error": ErrorEvent;
}
interface IDBDatabase extends EventTarget {
readonly name: string;
readonly objectStoreNames: DOMStringList;
onabort: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onabort: (this: IDBDatabase, ev: Event) => any;
onerror: (this: IDBDatabase, ev: ErrorEvent) => any;
version: number;
onversionchange: (ev: IDBVersionChangeEvent) => any;
close(): void;
@@ -351,8 +360,7 @@ interface IDBDatabase extends EventTarget {
deleteObjectStore(name: string): void;
transaction(storeNames: string | string[], mode?: string): IDBTransaction;
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -429,13 +437,15 @@ declare var IDBObjectStore: {
new(): IDBObjectStore;
}
interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
"blocked": Event;
"upgradeneeded": IDBVersionChangeEvent;
}
interface IDBOpenDBRequest extends IDBRequest {
onblocked: (this: this, ev: Event) => any;
onupgradeneeded: (this: this, ev: IDBVersionChangeEvent) => any;
addEventListener(type: "blocked", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "success", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "upgradeneeded", listener: (this: this, ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
onblocked: (this: IDBOpenDBRequest, ev: Event) => any;
onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any;
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -444,16 +454,20 @@ declare var IDBOpenDBRequest: {
new(): IDBOpenDBRequest;
}
interface IDBRequestEventMap {
"error": ErrorEvent;
"success": Event;
}
interface IDBRequest extends EventTarget {
readonly error: DOMError;
onerror: (this: this, ev: ErrorEvent) => any;
onsuccess: (this: this, ev: Event) => any;
onerror: (this: IDBRequest, ev: ErrorEvent) => any;
onsuccess: (this: IDBRequest, ev: Event) => any;
readonly readyState: string;
readonly result: any;
source: IDBObjectStore | IDBIndex | IDBCursor;
readonly transaction: IDBTransaction;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "success", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -462,21 +476,25 @@ declare var IDBRequest: {
new(): IDBRequest;
}
interface IDBTransactionEventMap {
"abort": Event;
"complete": Event;
"error": ErrorEvent;
}
interface IDBTransaction extends EventTarget {
readonly db: IDBDatabase;
readonly error: DOMError;
readonly mode: string;
onabort: (this: this, ev: Event) => any;
oncomplete: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onabort: (this: IDBTransaction, ev: Event) => any;
oncomplete: (this: IDBTransaction, ev: Event) => any;
onerror: (this: IDBTransaction, ev: ErrorEvent) => any;
abort(): void;
objectStore(name: string): IDBObjectStore;
readonly READ_ONLY: string;
readonly READ_WRITE: string;
readonly VERSION_CHANGE: string;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "complete", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -533,18 +551,22 @@ interface MSApp {
}
declare var MSApp: MSApp;
interface MSAppAsyncOperationEventMap {
"complete": Event;
"error": ErrorEvent;
}
interface MSAppAsyncOperation extends EventTarget {
readonly error: DOMError;
oncomplete: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
oncomplete: (this: MSAppAsyncOperation, ev: Event) => any;
onerror: (this: MSAppAsyncOperation, ev: ErrorEvent) => any;
readonly readyState: number;
readonly result: any;
start(): void;
readonly COMPLETED: number;
readonly ERROR: number;
readonly STARTED: number;
addEventListener(type: "complete", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof MSAppAsyncOperationEventMap>(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -584,6 +606,7 @@ interface MSStreamReader extends EventTarget, MSBaseReader {
readAsBlob(stream: MSStream, size?: number): void;
readAsDataURL(stream: MSStream, size?: number): void;
readAsText(stream: MSStream, encoding?: string, size?: number): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -627,12 +650,16 @@ declare var MessageEvent: {
new(type: string, eventInitDict?: MessageEventInit): MessageEvent;
}
interface MessagePortEventMap {
"message": MessageEvent;
}
interface MessagePort extends EventTarget {
onmessage: (this: this, ev: MessageEvent) => any;
onmessage: (this: MessagePort, ev: MessageEvent) => any;
close(): void;
postMessage(message?: any, ports?: any): void;
start(): void;
addEventListener(type: "message", listener: (this: this, ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -680,14 +707,21 @@ declare var ProgressEvent: {
new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent;
}
interface WebSocketEventMap {
"close": CloseEvent;
"error": ErrorEvent;
"message": MessageEvent;
"open": Event;
}
interface WebSocket extends EventTarget {
binaryType: string;
readonly bufferedAmount: number;
readonly extensions: string;
onclose: (this: this, ev: CloseEvent) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onmessage: (this: this, ev: MessageEvent) => any;
onopen: (this: this, ev: Event) => any;
onclose: (this: WebSocket, ev: CloseEvent) => any;
onerror: (this: WebSocket, ev: ErrorEvent) => any;
onmessage: (this: WebSocket, ev: MessageEvent) => any;
onopen: (this: WebSocket, ev: Event) => any;
readonly protocol: string;
readonly readyState: number;
readonly url: string;
@@ -697,10 +731,7 @@ interface WebSocket extends EventTarget {
readonly CLOSING: number;
readonly CONNECTING: number;
readonly OPEN: number;
addEventListener(type: "close", listener: (this: this, ev: CloseEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "message", listener: (this: this, ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener(type: "open", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -713,12 +744,15 @@ declare var WebSocket: {
readonly OPEN: number;
}
interface WorkerEventMap extends AbstractWorkerEventMap {
"message": MessageEvent;
}
interface Worker extends EventTarget, AbstractWorker {
onmessage: (this: this, ev: MessageEvent) => any;
onmessage: (this: Worker, ev: MessageEvent) => any;
postMessage(message: any, ports?: any): void;
terminate(): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "message", listener: (this: this, ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -727,8 +761,12 @@ declare var Worker: {
new(stringUrl: string): Worker;
}
interface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {
"readystatechange": Event;
}
interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
onreadystatechange: (this: this, ev: Event) => any;
onreadystatechange: (this: XMLHttpRequest, ev: Event) => any;
readonly readyState: number;
readonly response: any;
readonly responseText: string;
@@ -755,14 +793,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener(type: "abort", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -778,6 +809,7 @@ declare var XMLHttpRequest: {
}
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -786,31 +818,39 @@ declare var XMLHttpRequestUpload: {
new(): XMLHttpRequestUpload;
}
interface AbstractWorkerEventMap {
"error": ErrorEvent;
}
interface AbstractWorker {
onerror: (this: this, ev: ErrorEvent) => any;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
onerror: (this: AbstractWorker, ev: ErrorEvent) => any;
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface MSBaseReaderEventMap {
"abort": Event;
"error": ErrorEvent;
"load": Event;
"loadend": ProgressEvent;
"loadstart": Event;
"progress": ProgressEvent;
}
interface MSBaseReader {
onabort: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onload: (this: this, ev: Event) => any;
onloadend: (this: this, ev: ProgressEvent) => any;
onloadstart: (this: this, ev: Event) => any;
onprogress: (this: this, ev: ProgressEvent) => any;
onabort: (this: MSBaseReader, ev: Event) => any;
onerror: (this: MSBaseReader, ev: ErrorEvent) => any;
onload: (this: MSBaseReader, ev: Event) => any;
onloadend: (this: MSBaseReader, ev: ProgressEvent) => any;
onloadstart: (this: MSBaseReader, ev: Event) => any;
onprogress: (this: MSBaseReader, ev: ProgressEvent) => any;
readonly readyState: number;
readonly result: any;
abort(): void;
readonly DONE: number;
readonly EMPTY: number;
readonly LOADING: number;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -838,21 +878,25 @@ interface WindowConsole {
readonly console: Console;
}
interface XMLHttpRequestEventTargetEventMap {
"abort": Event;
"error": ErrorEvent;
"load": Event;
"loadend": ProgressEvent;
"loadstart": Event;
"progress": ProgressEvent;
"timeout": ProgressEvent;
}
interface XMLHttpRequestEventTarget {
onabort: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onload: (this: this, ev: Event) => any;
onloadend: (this: this, ev: ProgressEvent) => any;
onloadstart: (this: this, ev: Event) => any;
onprogress: (this: this, ev: ProgressEvent) => any;
ontimeout: (this: this, ev: ProgressEvent) => any;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
onabort: (this: XMLHttpRequestEventTarget, ev: Event) => any;
onerror: (this: XMLHttpRequestEventTarget, ev: ErrorEvent) => any;
onload: (this: XMLHttpRequestEventTarget, ev: Event) => any;
onloadend: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
onloadstart: (this: XMLHttpRequestEventTarget, ev: Event) => any;
onprogress: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
ontimeout: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -868,15 +912,18 @@ declare var FileReaderSync: {
new(): FileReaderSync;
}
interface WorkerGlobalScopeEventMap extends DedicatedWorkerGlobalScopeEventMap {
"error": ErrorEvent;
}
interface WorkerGlobalScope extends EventTarget, WorkerUtils, DedicatedWorkerGlobalScope, WindowConsole {
readonly location: WorkerLocation;
onerror: (this: this, ev: ErrorEvent) => any;
onerror: (this: WorkerGlobalScope, ev: ErrorEvent) => any;
readonly self: WorkerGlobalScope;
close(): void;
msWriteProfilerMark(profilerMarkName: string): void;
toString(): string;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "message", listener: (this: this, ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -904,7 +951,6 @@ declare var WorkerLocation: {
interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine {
readonly hardwareConcurrency: number;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
declare var WorkerNavigator: {
@@ -912,10 +958,14 @@ declare var WorkerNavigator: {
new(): WorkerNavigator;
}
interface DedicatedWorkerGlobalScopeEventMap {
"message": MessageEvent;
}
interface DedicatedWorkerGlobalScope {
onmessage: (this: this, ev: MessageEvent) => any;
onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any;
postMessage(data: any): void;
addEventListener(type: "message", listener: (this: this, ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -1176,7 +1226,6 @@ declare var self: WorkerGlobalScope;
declare function close(): void;
declare function msWriteProfilerMark(profilerMarkName: string): void;
declare function toString(): string;
declare function addEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare function dispatchEvent(evt: Event): boolean;
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare var indexedDB: IDBFactory;
@@ -1197,8 +1246,7 @@ declare function btoa(rawString: string): string;
declare var onmessage: (this: WorkerGlobalScope, ev: MessageEvent) => any;
declare function postMessage(data: any): void;
declare var console: Console;
declare function addEventListener(type: "error", listener: (this: WorkerGlobalScope, ev: ErrorEvent) => any, useCapture?: boolean): void;
declare function addEventListener(type: "message", listener: (this: WorkerGlobalScope, ev: MessageEvent) => any, useCapture?: boolean): void;
declare function addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
type AlgorithmIdentifier = string | Algorithm;
type IDBKeyPath = string;
+35 -17
View File
@@ -257,7 +257,7 @@ namespace ts.server {
private changedFiles: ScriptInfo[];
private toCanonicalFileName: (f: string) => string;
readonly toCanonicalFileName: (f: string) => string;
public lastDeletedFile: ScriptInfo;
@@ -317,7 +317,7 @@ namespace ts.server {
}
switch (response.kind) {
case ActionSet:
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.unresolvedImports, response.typings);
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings);
break;
case ActionInvalidate:
this.typingsCache.deleteTypingsForProject(response.projectName);
@@ -520,8 +520,10 @@ namespace ts.server {
}
private onConfigChangedForConfiguredProject(project: ConfiguredProject) {
this.logger.info(`Config file changed: ${project.getConfigFilePath()}`);
this.updateConfiguredProject(project);
const configFileName = project.getConfigFilePath();
this.logger.info(`Config file changed: ${configFileName}`);
const configFileErrors = this.updateConfiguredProject(project);
this.reportConfigFileDiagnostics(configFileName, configFileErrors, /*triggerFile*/ configFileName);
this.refreshInferredProjects();
}
@@ -775,7 +777,13 @@ namespace ts.server {
}
private findConfiguredProjectByProjectName(configFileName: NormalizedPath) {
return findProjectByName(configFileName, this.configuredProjects);
// make sure that casing of config file name is consistent
configFileName = asNormalizedPath(this.toCanonicalFileName(configFileName));
for (const proj of this.configuredProjects) {
if (proj.canonicalConfigFilePath === configFileName) {
return proj;
}
}
}
private findExternalProjectByProjectName(projectFileName: string) {
@@ -821,7 +829,7 @@ namespace ts.server {
compilerOptions: parsedCommandLine.options,
configHasFilesProperty: config["files"] !== undefined,
wildcardDirectories: createMap(parsedCommandLine.wildcardDirectories),
typingOptions: parsedCommandLine.typingOptions,
typeAcquisition: parsedCommandLine.typeAcquisition,
compileOnSave: parsedCommandLine.compileOnSave
};
return { success: true, projectOptions, configFileErrors: errors };
@@ -845,7 +853,7 @@ namespace ts.server {
return false;
}
private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typingOptions: TypingOptions) {
private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) {
const compilerOptions = convertCompilerOptions(options);
const project = new ExternalProject(
projectFileName,
@@ -855,7 +863,7 @@ namespace ts.server {
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
options.compileOnSave === undefined ? true : options.compileOnSave);
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typingOptions, /*configFileErrors*/ undefined);
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined);
this.externalProjects.push(project);
return project;
}
@@ -883,7 +891,7 @@ namespace ts.server {
/*languageServiceEnabled*/ !sizeLimitExceeded,
projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave);
this.addFilesToProjectAndUpdateGraph(project, projectOptions.files, fileNamePropertyReader, clientFileName, projectOptions.typingOptions, configFileErrors);
this.addFilesToProjectAndUpdateGraph(project, projectOptions.files, fileNamePropertyReader, clientFileName, projectOptions.typeAcquisition, configFileErrors);
project.watchConfigFile(project => this.onConfigChangedForConfiguredProject(project));
if (!sizeLimitExceeded) {
@@ -902,7 +910,7 @@ namespace ts.server {
}
}
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typingOptions: TypingOptions, configFileErrors: Diagnostic[]): void {
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: Diagnostic[]): void {
let errors: Diagnostic[];
for (const f of files) {
const rootFilename = propertyReader.getFileName(f);
@@ -917,7 +925,7 @@ namespace ts.server {
}
}
project.setProjectErrors(concatenate(configFileErrors, errors));
project.setTypingOptions(typingOptions);
project.setTypeAcquisition(typeAcquisition);
project.updateGraph();
}
@@ -934,7 +942,7 @@ namespace ts.server {
};
}
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypingOptions: TypingOptions, compileOnSave: boolean, configFileErrors: Diagnostic[]) {
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean, configFileErrors: Diagnostic[]) {
const oldRootScriptInfos = project.getRootScriptInfos();
const newRootScriptInfos: ScriptInfo[] = [];
const newRootScriptInfoMap: NormalizedPathMap<ScriptInfo> = createNormalizedPathMap<ScriptInfo>();
@@ -996,7 +1004,7 @@ namespace ts.server {
}
project.setCompilerOptions(newOptions);
(<ExternalProject | ConfiguredProject>project).setTypingOptions(newTypingOptions);
(<ExternalProject | ConfiguredProject>project).setTypeAcquisition(newTypeAcquisition);
// VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
// therefore if it is undefined, it should not be updated.
@@ -1015,6 +1023,9 @@ namespace ts.server {
return;
}
// note: the returned "success" is true does not mean the "configFileErrors" is empty.
// because we might have tolerated the errors and kept going. So always return the configFileErrors
// regardless the "success" here is true or not.
const { success, projectOptions, configFileErrors } = this.convertConfigFileContentToProjectOptions(project.getConfigFilePath());
if (!success) {
// reset project settings to default
@@ -1026,7 +1037,7 @@ namespace ts.server {
project.setCompilerOptions(projectOptions.compilerOptions);
if (!project.languageServiceEnabled) {
// language service is already disabled
return;
return configFileErrors;
}
project.disableLanguageService();
project.stopWatchingDirectory();
@@ -1036,8 +1047,9 @@ namespace ts.server {
project.enableLanguageService();
}
this.watchConfigDirectoryForProject(project, projectOptions);
this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typingOptions, projectOptions.compileOnSave, configFileErrors);
this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave, configFileErrors);
}
return configFileErrors;
}
createInferredProjectWithRootFileIfNecessary(root: ScriptInfo) {
@@ -1316,6 +1328,12 @@ namespace ts.server {
}
openExternalProject(proj: protocol.ExternalProject): void {
// typingOptions has been deprecated and is only supported for backward compatibility
// purposes. It should be removed in future releases - use typeAcquisition instead.
if (proj.typingOptions && !proj.typeAcquisition) {
const typeAcquisition = convertEnableAutoDiscoveryToEnable(proj.typingOptions);
proj.typeAcquisition = typeAcquisition;
}
let tsConfigFiles: NormalizedPath[];
const rootFiles: protocol.ExternalFile[] = [];
for (const file of proj.rootFiles) {
@@ -1340,7 +1358,7 @@ namespace ts.server {
if (externalProject) {
if (!tsConfigFiles) {
// external project already exists and not config files were added - update the project and return;
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typeAcquisition, proj.options.compileOnSave, /*configFileErrors*/ undefined);
return;
}
// some config files were added to external project (that previously were not there)
@@ -1400,7 +1418,7 @@ namespace ts.server {
else {
// no config files - remove the item from the collection
delete this.externalProjectToConfiguredProjectMap[proj.projectFileName];
this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typingOptions);
this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
}
this.refreshInferredProjects();
}
+1 -1
View File
@@ -23,7 +23,7 @@ namespace ts.server {
}
this.resolveModuleName = (moduleName, containingFile, compilerOptions, host) => {
const globalCache = this.project.getTypingOptions().enableAutoDiscovery
const globalCache = this.project.getTypeAcquisition().enable
? this.project.projectService.typingsInstaller.globalTypingsCacheLocation
: undefined;
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
+24 -22
View File
@@ -312,7 +312,7 @@ namespace ts.server {
return this.projectName;
}
abstract getProjectRootPath(): string | undefined;
abstract getTypingOptions(): TypingOptions;
abstract getTypeAcquisition(): TypeAcquisition;
getSourceFile(path: Path) {
if (!this.program) {
@@ -802,9 +802,9 @@ namespace ts.server {
}
}
getTypingOptions(): TypingOptions {
getTypeAcquisition(): TypeAcquisition {
return {
enableAutoDiscovery: allRootFilesAreJsOrDts(this),
enable: allRootFilesAreJsOrDts(this),
include: [],
exclude: []
};
@@ -812,11 +812,12 @@ namespace ts.server {
}
export class ConfiguredProject extends Project {
private typingOptions: TypingOptions;
private typeAcquisition: TypeAcquisition;
private projectFileWatcher: FileWatcher;
private directoryWatcher: FileWatcher;
private directoriesWatchedForWildcards: Map<FileWatcher>;
private typeRootsWatchers: FileWatcher[];
readonly canonicalConfigFilePath: NormalizedPath;
/** Used for configured projects which may have multiple open roots */
openRefCount = 0;
@@ -830,6 +831,7 @@ namespace ts.server {
languageServiceEnabled: boolean,
public compileOnSaveEnabled: boolean) {
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
}
getConfigFilePath() {
@@ -844,12 +846,12 @@ namespace ts.server {
this.projectErrors = projectErrors;
}
setTypingOptions(newTypingOptions: TypingOptions): void {
this.typingOptions = newTypingOptions;
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void {
this.typeAcquisition = newTypeAcquisition;
}
getTypingOptions() {
return this.typingOptions;
getTypeAcquisition() {
return this.typeAcquisition;
}
watchConfigFile(callback: (project: ConfiguredProject) => void) {
@@ -939,7 +941,7 @@ namespace ts.server {
}
export class ExternalProject extends Project {
private typingOptions: TypingOptions;
private typeAcquisition: TypeAcquisition;
constructor(externalProjectName: string,
projectService: ProjectService,
documentRegistry: ts.DocumentRegistry,
@@ -960,36 +962,36 @@ namespace ts.server {
return getDirectoryPath(normalizeSlashes(this.getProjectName()));
}
getTypingOptions() {
return this.typingOptions;
getTypeAcquisition() {
return this.typeAcquisition;
}
setProjectErrors(projectErrors: Diagnostic[]) {
this.projectErrors = projectErrors;
}
setTypingOptions(newTypingOptions: TypingOptions): void {
if (!newTypingOptions) {
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void {
if (!newTypeAcquisition) {
// set default typings options
newTypingOptions = {
enableAutoDiscovery: allRootFilesAreJsOrDts(this),
newTypeAcquisition = {
enable: allRootFilesAreJsOrDts(this),
include: [],
exclude: []
};
}
else {
if (newTypingOptions.enableAutoDiscovery === undefined) {
if (newTypeAcquisition.enable === undefined) {
// if autoDiscovery was not specified by the caller - set it based on the content of the project
newTypingOptions.enableAutoDiscovery = allRootFilesAreJsOrDts(this);
newTypeAcquisition.enable = allRootFilesAreJsOrDts(this);
}
if (!newTypingOptions.include) {
newTypingOptions.include = [];
if (!newTypeAcquisition.include) {
newTypeAcquisition.include = [];
}
if (!newTypingOptions.exclude) {
newTypingOptions.exclude = [];
if (!newTypeAcquisition.exclude) {
newTypeAcquisition.exclude = [];
}
}
this.typingOptions = newTypingOptions;
this.typeAcquisition = newTypeAcquisition;
}
}
}
+40 -2
View File
@@ -861,9 +861,13 @@ namespace ts.server.protocol {
*/
options: ExternalProjectCompilerOptions;
/**
* Explicitly specified typing options for the project
* @deprecated typingOptions. Use typeAcquisition instead
*/
typingOptions?: TypingOptions;
typingOptions?: TypeAcquisition;
/**
* Explicitly specified type acquisition for the project
*/
typeAcquisition?: TypeAcquisition;
}
export interface CompileOnSaveMixin {
@@ -2113,6 +2117,40 @@ namespace ts.server.protocol {
typingsInstallerVersion: string;
}
export type BeginInstallTypesEventName = "beginInstallTypes";
export type EndInstallTypesEventName = "endInstallTypes";
export interface BeginInstallTypesEvent extends Event {
event: BeginInstallTypesEventName;
body: BeginInstallTypesEventBody;
}
export interface EndInstallTypesEvent extends Event {
event: EndInstallTypesEventName;
body: EndInstallTypesEventBody;
}
export interface InstallTypesEventBody {
/**
* correlation id to match begin and end events
*/
eventId: number;
/**
* list of packages to install
*/
packages: ReadonlyArray<string>;
}
export interface BeginInstallTypesEventBody extends InstallTypesEventBody {
}
export interface EndInstallTypesEventBody extends InstallTypesEventBody {
/**
* true if installation succeeded, otherwise false
*/
success: boolean;
}
export interface NavBarResponse extends Response {
body?: NavigationBarItem[];
}
+42 -9
View File
@@ -31,6 +31,7 @@ namespace ts.server {
os.tmpdir();
break;
case "linux":
case "android":
basePath = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/home/${process.env.LOGNAME || process.env.USER}`) ||
@@ -197,7 +198,7 @@ namespace ts.server {
private socket: NodeSocket;
private projectService: ProjectService;
private throttledOperations: ThrottledOperations;
private telemetrySender: EventSender;
private eventSender: EventSender;
constructor(
private readonly telemetryEnabled: boolean,
@@ -230,7 +231,7 @@ namespace ts.server {
}
setTelemetrySender(telemetrySender: EventSender) {
this.telemetrySender = telemetrySender;
this.eventSender = telemetrySender;
}
attach(projectService: ProjectService) {
@@ -275,8 +276,8 @@ namespace ts.server {
this.installer.send({ projectName: p.getProjectName(), kind: "closeProject" });
}
enqueueInstallTypingsRequest(project: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>): void {
const request = createInstallTypingsRequest(project, typingOptions, unresolvedImports);
enqueueInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void {
const request = createInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
if (this.logger.hasLevel(LogLevel.verbose)) {
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Scheduling throttled operation: ${JSON.stringify(request)}`);
@@ -290,12 +291,30 @@ namespace ts.server {
});
}
private handleMessage(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent) {
private handleMessage(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes) {
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Received response: ${JSON.stringify(response)}`);
}
if (response.kind === EventInstall) {
if (this.telemetrySender) {
if (response.kind === EventBeginInstallTypes) {
if (!this.eventSender) {
return;
}
const body: protocol.BeginInstallTypesEventBody = {
eventId: response.eventId,
packages: response.packagesToInstall,
};
const eventName: protocol.BeginInstallTypesEventName = "beginInstallTypes";
this.eventSender.event(body, eventName);
return;
}
if (response.kind === EventEndInstallTypes) {
if (!this.eventSender) {
return;
}
if (this.telemetryEnabled) {
const body: protocol.TypingsInstalledTelemetryEventBody = {
telemetryEventName: "typingsInstalled",
payload: {
@@ -305,10 +324,19 @@ namespace ts.server {
}
};
const eventName: protocol.TelemetryEventName = "telemetry";
this.telemetrySender.event(body, eventName);
this.eventSender.event(body, eventName);
}
const body: protocol.EndInstallTypesEventBody = {
eventId: response.eventId,
packages: response.packagesToInstall,
success: response.installSuccess,
};
const eventName: protocol.EndInstallTypesEventName = "endInstallTypes";
this.eventSender.event(body, eventName);
return;
}
this.projectService.updateTypingsForProject(response);
if (response.kind == ActionSet && this.socket) {
this.sendEvent(0, "setTypings", response);
@@ -577,6 +605,11 @@ namespace ts.server {
}
}
const localeStr = findArgument("--locale");
if (localeStr) {
validateLocaleAndSetLanguage(localeStr, sys);
}
const useSingleInferredProject = hasArgument("--useSingleInferredProject");
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
@@ -598,4 +631,4 @@ namespace ts.server {
(process as any).noAsar = true;
// Start listening
ioSession.listen();
}
}
+2 -1
View File
@@ -3,7 +3,8 @@
namespace ts.server {
export const ActionSet: ActionSet = "action::set";
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
export const EventInstall: EventInstall = "event::install";
export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes";
export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes";
export namespace Arguments {
export const GlobalCacheLocation = "--globalTypingsCacheLocation";
+18 -8
View File
@@ -31,7 +31,7 @@ declare namespace ts.server {
readonly fileNames: string[];
readonly projectRootPath: ts.Path;
readonly compilerOptions: ts.CompilerOptions;
readonly typingOptions: ts.TypingOptions;
readonly typeAcquisition: ts.TypeAcquisition;
readonly unresolvedImports: SortedReadonlyArray<string>;
readonly cachePath?: string;
readonly kind: "discover";
@@ -43,10 +43,11 @@ declare namespace ts.server {
export type ActionSet = "action::set";
export type ActionInvalidate = "action::invalidate";
export type EventInstall = "event::install";
export type EventBeginInstallTypes = "event::beginInstallTypes";
export type EventEndInstallTypes = "event::endInstallTypes";
export interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventInstall;
readonly kind: ActionSet | ActionInvalidate | EventBeginInstallTypes | EventEndInstallTypes;
}
export interface ProjectResponse extends TypingInstallerResponse {
@@ -54,7 +55,7 @@ declare namespace ts.server {
}
export interface SetTypings extends ProjectResponse {
readonly typingOptions: ts.TypingOptions;
readonly typeAcquisition: ts.TypeAcquisition;
readonly compilerOptions: ts.CompilerOptions;
readonly typings: string[];
readonly unresolvedImports: SortedReadonlyArray<string>;
@@ -65,11 +66,20 @@ declare namespace ts.server {
readonly kind: ActionInvalidate;
}
export interface TypingsInstallEvent extends TypingInstallerResponse {
readonly packagesToInstall: ReadonlyArray<string>;
readonly kind: EventInstall;
readonly installSuccess: boolean;
export interface InstallTypes extends ProjectResponse {
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
readonly eventId: number;
readonly typingsInstallerVersion: string;
readonly packagesToInstall: ReadonlyArray<string>;
}
export interface BeginInstallTypes extends InstallTypes {
readonly kind: EventBeginInstallTypes;
}
export interface EndInstallTypes extends InstallTypes {
readonly kind: EventEndInstallTypes;
readonly installSuccess: boolean;
}
export interface InstallTypingHost extends JsTyping.TypingResolutionHost {
+11 -11
View File
@@ -2,7 +2,7 @@
namespace ts.server {
export interface ITypingsInstaller {
enqueueInstallTypingsRequest(p: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>): void;
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
attach(projectService: ProjectService): void;
onProjectClosed(p: Project): void;
readonly globalTypingsCacheLocation: string;
@@ -16,7 +16,7 @@ namespace ts.server {
};
class TypingsCacheEntry {
readonly typingOptions: TypingOptions;
readonly typeAcquisition: TypeAcquisition;
readonly compilerOptions: CompilerOptions;
readonly typings: SortedReadonlyArray<string>;
readonly unresolvedImports: SortedReadonlyArray<string>;
@@ -52,8 +52,8 @@ namespace ts.server {
return unique === 0;
}
function typingOptionsChanged(opt1: TypingOptions, opt2: TypingOptions): boolean {
return opt1.enableAutoDiscovery !== opt2.enableAutoDiscovery ||
function typeAcquisitionChanged(opt1: TypeAcquisition, opt2: TypeAcquisition): boolean {
return opt1.enable !== opt2.enable ||
!setIsEqualTo(opt1.include, opt2.include) ||
!setIsEqualTo(opt1.exclude, opt2.exclude);
}
@@ -77,9 +77,9 @@ namespace ts.server {
}
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string> {
const typingOptions = project.getTypingOptions();
const typeAcquisition = project.getTypeAcquisition();
if (!typingOptions || !typingOptions.enableAutoDiscovery) {
if (!typeAcquisition || !typeAcquisition.enable) {
return <any>emptyArray;
}
@@ -87,28 +87,28 @@ namespace ts.server {
const result: SortedReadonlyArray<string> = entry ? entry.typings : <any>emptyArray;
if (forceRefresh ||
!entry ||
typingOptionsChanged(typingOptions, entry.typingOptions) ||
typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) ||
compilerOptionsChanged(project.getCompilerOptions(), entry.compilerOptions) ||
unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) {
// Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options.
// instead it acts as a placeholder to prevent issuing multiple requests
this.perProjectCache[project.getProjectName()] = {
compilerOptions: project.getCompilerOptions(),
typingOptions,
typeAcquisition,
typings: result,
unresolvedImports,
poisoned: true
};
// something has been changed, issue a request to update typings
this.installer.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
return result;
}
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
this.perProjectCache[projectName] = {
compilerOptions,
typingOptions,
typeAcquisition,
typings: toSortedReadonlyArray(newTypings),
unresolvedImports,
poisoned: false
@@ -70,13 +70,12 @@ namespace ts.server.typingsInstaller {
private readonly npmPath: string;
readonly typesRegistry: Map<void>;
constructor(globalTypingsCacheLocation: string, throttleLimit: number, telemetryEnabled: boolean, log: Log) {
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
telemetryEnabled,
log);
if (this.log.isEnabled()) {
this.log.writeLine(`Process id: ${process.pid}`);
@@ -113,7 +112,7 @@ namespace ts.server.typingsInstaller {
});
}
protected sendResponse(response: SetTypings | InvalidateCachedTypings) {
protected sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes) {
if (this.log.isEnabled()) {
this.log.writeLine(`Sending response: ${JSON.stringify(response)}`);
}
@@ -127,7 +126,7 @@ namespace ts.server.typingsInstaller {
if (this.log.isEnabled()) {
this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(args)}'.`);
}
const command = `${this.npmPath} install ${args.join(" ")} --save-dev`;
const command = `${this.npmPath} install ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`;
const start = Date.now();
let stdout: Buffer;
let stderr: Buffer;
@@ -149,7 +148,6 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const telemetryEnabled = hasArgument(server.Arguments.EnableTelemetry);
const log = new FileLog(logFilePath);
if (log.isEnabled()) {
@@ -163,6 +161,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, telemetryEnabled, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log);
installer.listen();
}
+49 -39
View File
@@ -97,7 +97,6 @@ namespace ts.server.typingsInstaller {
readonly globalCachePath: string,
readonly safeListPath: Path,
readonly throttleLimit: number,
readonly telemetryEnabled: boolean,
protected readonly log = nullLog) {
if (this.log.isEnabled()) {
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`);
@@ -150,7 +149,7 @@ namespace ts.server.typingsInstaller {
req.projectRootPath,
this.safeListPath,
this.packageNameToTypingLocation,
req.typingOptions,
req.typeAcquisition,
req.unresolvedImports);
if (this.log.isEnabled()) {
@@ -309,47 +308,58 @@ namespace ts.server.typingsInstaller {
const requestId = this.installRunCount;
this.installRunCount++;
// send progress event
this.sendResponse(<BeginInstallTypes>{
kind: EventBeginInstallTypes,
eventId: requestId,
typingsInstallerVersion: ts.version, // qualified explicitly to prevent occasional shadowing
projectName: req.projectName
});
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
if (this.telemetryEnabled) {
this.sendResponse(<TypingsInstallEvent>{
kind: EventInstall,
try {
if (!ok) {
if (this.log.isEnabled()) {
this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
}
for (const typing of filteredTypings) {
this.missingTypingsSet[typing] = true;
}
return;
}
// TODO: watch project directory
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`);
}
const installedTypingFiles: string[] = [];
for (const packageName of filteredTypings) {
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
if (!typingFile) {
this.missingTypingsSet[packageName] = true;
continue;
}
if (!this.packageNameToTypingLocation[packageName]) {
this.packageNameToTypingLocation[packageName] = typingFile;
}
installedTypingFiles.push(typingFile);
}
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
}
this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
}
finally {
this.sendResponse(<EndInstallTypes>{
kind: EventEndInstallTypes,
eventId: requestId,
projectName: req.projectName,
packagesToInstall: scopedTypings,
installSuccess: ok,
typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing
});
}
if (!ok) {
if (this.log.isEnabled()) {
this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
}
for (const typing of filteredTypings) {
this.missingTypingsSet[typing] = true;
}
return;
}
// TODO: watch project directory
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`);
}
const installedTypingFiles: string[] = [];
for (const packageName of filteredTypings) {
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
if (!typingFile) {
this.missingTypingsSet[packageName] = true;
continue;
}
if (!this.packageNameToTypingLocation[packageName]) {
this.packageNameToTypingLocation[packageName] = typingFile;
}
installedTypingFiles.push(typingFile);
}
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
}
this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
});
}
@@ -391,7 +401,7 @@ namespace ts.server.typingsInstaller {
private createSetTypings(request: DiscoverTypings, typings: string[]): SetTypings {
return {
projectName: request.projectName,
typingOptions: request.typingOptions,
typeAcquisition: request.typeAcquisition,
compilerOptions: request.compilerOptions,
typings,
unresolvedImports: request.unresolvedImports,
@@ -417,6 +427,6 @@ namespace ts.server.typingsInstaller {
}
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
}
}
+3 -3
View File
@@ -46,12 +46,12 @@ namespace ts.server {
}
}
export function createInstallTypingsRequest(project: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
return {
projectName: project.getProjectName(),
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true),
compilerOptions: project.getCompilerOptions(),
typingOptions,
typeAcquisition,
unresolvedImports,
projectRootPath: getProjectRootPath(project),
cachePath,
@@ -171,7 +171,7 @@ namespace ts.server {
files?: string[];
wildcardDirectories?: Map<WatchDirectoryFlags>;
compilerOptions?: CompilerOptions;
typingOptions?: TypingOptions;
typeAcquisition?: TypeAcquisition;
compileOnSave?: boolean;
}
+3 -3
View File
@@ -52,7 +52,7 @@ namespace ts.codefix {
// than another existing one. For example, you may have new imports from "./foo/bar"
// and "bar", when the new one is "bar/bar2" and the current one is "./foo/bar". The new
// one and the current one are not comparable (one relative path and one absolute path),
// but the new one is worse than the other one, so should not add to the list.
// but the new one is worse than the other one, so should not add to the list.
updatedNewImports.push(existingAction);
break;
case ModuleSpecifierComparison.Worse:
@@ -145,7 +145,7 @@ namespace ts.codefix {
if (localSymbol && localSymbol.name === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
// check if this symbol is already used
const symbolId = getUniqueSymbolId(localSymbol);
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, /*isDefaultExport*/ true));
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, /*isDefault*/ true));
}
}
@@ -483,7 +483,7 @@ namespace ts.codefix {
const normalizedTypeRoots = map(typeRoots, typeRoot => toPath(typeRoot, /*basePath*/ undefined, getCanonicalFileName));
for (const typeRoot of normalizedTypeRoots) {
if (startsWith(moduleFileName, typeRoot)) {
let relativeFileName = moduleFileName.substring(typeRoot.length + 1);
const relativeFileName = moduleFileName.substring(typeRoot.length + 1);
return removeExtensionAndIndexPostFix(relativeFileName);
}
}
+14 -1
View File
@@ -886,12 +886,25 @@ namespace ts.formatting {
else {
const tokenStart = sourceFile.getLineAndCharacterOfPosition(pos);
const startLinePosition = getStartPositionOfLine(tokenStart.line, sourceFile);
if (indentation !== tokenStart.character || indentationIsDifferent(indentationString, startLinePosition)) {
if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) {
recordReplace(startLinePosition, tokenStart.character, indentationString);
}
}
}
function characterToColumn(startLinePosition: number, characterInLine: number): number {
let column = 0;
for (let i = 0; i < characterInLine; i++) {
if (sourceFile.text.charCodeAt(startLinePosition + i) === CharacterCodes.tab) {
column += options.tabSize - column % options.tabSize;
}
else {
column++;
}
}
return column;
}
function indentationIsDifferent(indentationString: string, startLinePosition: number): boolean {
return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
}
+1 -1
View File
@@ -52,7 +52,7 @@ namespace ts.JsDoc {
// from Array<T> - Array<string> and Array<number>
const documentationComment = <SymbolDisplayPart[]>[];
forEachUnique(declarations, declaration => {
const comments = getJSDocComments(declaration, /*checkParentVariableStatement*/ true);
const comments = getCommentsFromJSDoc(declaration);
if (!comments) {
return;
}
+5 -5
View File
@@ -48,7 +48,7 @@ namespace ts.JsTyping {
* @param projectRootPath is the path to the project root directory
* @param safeListPath is the path used to retrieve the safe list
* @param packageNameToTypingLocation is the map of package names to their cached typing locations
* @param typingOptions are used to customize the typing inference process
* @param typeAcquisition is used to customize the typing acquisition process
* @param compilerOptions are used as a source for typing inference
*/
export function discoverTypings(
@@ -57,14 +57,14 @@ namespace ts.JsTyping {
projectRootPath: Path,
safeListPath: Path,
packageNameToTypingLocation: Map<string>,
typingOptions: TypingOptions,
typeAcquisition: TypeAcquisition,
unresolvedImports: ReadonlyArray<string>):
{ cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {
// A typing name to typing file path mapping
const inferredTypings = createMap<string>();
if (!typingOptions || !typingOptions.enableAutoDiscovery) {
if (!typeAcquisition || !typeAcquisition.enable) {
return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
}
@@ -84,8 +84,8 @@ namespace ts.JsTyping {
let searchDirs: string[] = [];
let exclude: string[] = [];
mergeTypings(typingOptions.include);
exclude = typingOptions.exclude || [];
mergeTypings(typeAcquisition.include);
exclude = typeAcquisition.exclude || [];
const possibleSearchDirs = map(fileNames, getDirectoryPath);
if (projectRootPath) {
+2 -2
View File
@@ -225,8 +225,8 @@ namespace ts.NavigationBar {
break;
default:
forEach(node.jsDocComments, jsDocComment => {
forEach(jsDocComment.tags, tag => {
forEach(node.jsDoc, jsDoc => {
forEach(jsDoc.tags, tag => {
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
addLeafNode(tag);
}
+6 -6
View File
@@ -45,7 +45,7 @@ namespace ts {
public end: number;
public flags: NodeFlags;
public parent: Node;
public jsDocComments: JSDoc[];
public jsDoc: JSDoc[];
public original: Node;
public transformFlags: TransformFlags;
private _children: Node[];
@@ -154,8 +154,8 @@ namespace ts {
pos = nodes.end;
};
// jsDocComments need to be the first children
if (this.jsDocComments) {
for (const jsDocComment of this.jsDocComments) {
if (this.jsDoc) {
for (const jsDocComment of this.jsDoc) {
processNode(jsDocComment);
}
}
@@ -1975,9 +1975,9 @@ namespace ts {
break;
default:
forEachChild(node, walk);
if (node.jsDocComments) {
for (const jsDocComment of node.jsDocComments) {
forEachChild(jsDocComment, walk);
if (node.jsDoc) {
for (const jsDoc of node.jsDoc) {
forEachChild(jsDoc, walk);
}
}
}
+3 -3
View File
@@ -1138,7 +1138,7 @@ namespace ts {
if (result.error) {
return {
options: {},
typingOptions: {},
typeAcquisition: {},
files: [],
raw: {},
errors: [realizeDiagnostic(result.error, "\r\n")]
@@ -1150,7 +1150,7 @@ namespace ts {
return {
options: configFile.options,
typingOptions: configFile.typingOptions,
typeAcquisition: configFile.typeAcquisition,
files: configFile.fileNames,
raw: configFile.raw,
errors: realizeDiagnostics(configFile.errors, "\r\n")
@@ -1175,7 +1175,7 @@ namespace ts {
toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName),
toPath(info.safeListPath, info.safeListPath, getCanonicalFileName),
info.packageNameToTypingLocation,
info.typingOptions,
info.typeAcquisition,
info.unresolvedImports);
});
}
+4 -4
View File
@@ -951,10 +951,10 @@ namespace ts {
}
if (node) {
if (node.jsDocComments) {
for (const jsDocComment of node.jsDocComments) {
if (jsDocComment.tags) {
for (const tag of jsDocComment.tags) {
if (node.jsDoc) {
for (const jsDoc of node.jsDoc) {
if (jsDoc.tags) {
for (const tag of jsDoc.tags) {
if (tag.pos <= position && position <= tag.end) {
return tag;
}
@@ -3,7 +3,7 @@
const fs = require("fs");
>fs : typeof "fs"
>require("fs") : typeof "fs"
>require("fs") : any
>require : (moduleName: string) => any
>"fs" : "fs"
@@ -0,0 +1,17 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts(4,17): error TS1318: An abstract accessor cannot have an implementation.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts(6,17): error TS1318: An abstract accessor cannot have an implementation.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts (2 errors) ====
abstract class A {
abstract get a();
abstract get aa() { return 1; } // error
~~
!!! error TS1318: An abstract accessor cannot have an implementation.
abstract set b(x: string);
abstract set bb(x: string) {} // error
~~
!!! error TS1318: An abstract accessor cannot have an implementation.
}
@@ -0,0 +1,28 @@
//// [classAbstractAccessor.ts]
abstract class A {
abstract get a();
abstract get aa() { return 1; } // error
abstract set b(x: string);
abstract set bb(x: string) {} // error
}
//// [classAbstractAccessor.js]
var A = (function () {
function A() {
}
Object.defineProperty(A.prototype, "aa", {
get: function () { return 1; } // error
,
enumerable: true,
configurable: true
});
Object.defineProperty(A.prototype, "bb", {
set: function (x) { } // error
,
enumerable: true,
configurable: true
});
return A;
}());
@@ -0,0 +1,14 @@
//// [commaOperatorInConditionalExpression.ts]
function f (m: string) {
[1, 2, 3].map(i => {
return true? { [m]: i } : { [m]: i + 1 }
})
}
//// [commaOperatorInConditionalExpression.js]
function f(m) {
[1, 2, 3].map(function (i) {
return true ? (_a = {}, _a[m] = i, _a) : (_b = {}, _b[m] = i + 1, _b);
var _a, _b;
});
}
@@ -0,0 +1,18 @@
=== tests/cases/compiler/commaOperatorInConditionalExpression.ts ===
function f (m: string) {
>f : Symbol(f, Decl(commaOperatorInConditionalExpression.ts, 0, 0))
>m : Symbol(m, Decl(commaOperatorInConditionalExpression.ts, 0, 12))
[1, 2, 3].map(i => {
>[1, 2, 3].map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>i : Symbol(i, Decl(commaOperatorInConditionalExpression.ts, 1, 18))
return true? { [m]: i } : { [m]: i + 1 }
>m : Symbol(m, Decl(commaOperatorInConditionalExpression.ts, 0, 12))
>i : Symbol(i, Decl(commaOperatorInConditionalExpression.ts, 1, 18))
>m : Symbol(m, Decl(commaOperatorInConditionalExpression.ts, 0, 12))
>i : Symbol(i, Decl(commaOperatorInConditionalExpression.ts, 1, 18))
})
}
@@ -0,0 +1,30 @@
=== tests/cases/compiler/commaOperatorInConditionalExpression.ts ===
function f (m: string) {
>f : (m: string) => void
>m : string
[1, 2, 3].map(i => {
>[1, 2, 3].map(i => { return true? { [m]: i } : { [m]: i + 1 } }) : { [x: string]: number; }[]
>[1, 2, 3].map : { <U>(this: [number, number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U]; <U>(this: [number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): U[]; }
>[1, 2, 3] : number[]
>1 : 1
>2 : 2
>3 : 3
>map : { <U>(this: [number, number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [number, number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [number, number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U, U]; <U>(this: [number, number], callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any): U[]; }
>i => { return true? { [m]: i } : { [m]: i + 1 } } : (i: number) => { [x: string]: number; }
>i : number
return true? { [m]: i } : { [m]: i + 1 }
>true? { [m]: i } : { [m]: i + 1 } : { [x: string]: number; }
>true : true
>{ [m]: i } : { [x: string]: number; }
>m : string
>i : number
>{ [m]: i + 1 } : { [x: string]: number; }
>m : string
>i + 1 : number
>i : number
>1 : 1
})
}
@@ -0,0 +1,188 @@
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,17): error TS7006: Parameter 'a' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,19): error TS7006: Parameter 'b' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,21): error TS7006: Parameter 'c' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,23): error TS7006: Parameter 'd' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,25): error TS7006: Parameter 'x' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,27): error TS7006: Parameter 's' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(6,29): error TS7006: Parameter 'ac' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,17): error TS7006: Parameter 'a' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,19): error TS7006: Parameter 'b' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,21): error TS7006: Parameter 'c' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,23): error TS7006: Parameter 'd' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,25): error TS7006: Parameter 'x' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,27): error TS7006: Parameter 's' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(10,29): error TS7006: Parameter 'ac' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,17): error TS7006: Parameter 'a' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,19): error TS7006: Parameter 'b' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,21): error TS7006: Parameter 'c' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,23): error TS7006: Parameter 'd' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,25): error TS7006: Parameter 'x' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,27): error TS7006: Parameter 's' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(14,29): error TS7006: Parameter 'ac' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,17): error TS7006: Parameter 'a' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,19): error TS7006: Parameter 'b' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,21): error TS7006: Parameter 'c' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,23): error TS7006: Parameter 'd' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,25): error TS7006: Parameter 'x' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,27): error TS7006: Parameter 's' implicitly has an 'any' type.
tests/cases/compiler/controlFlowSelfReferentialLoop.ts(18,29): error TS7006: Parameter 'ac' implicitly has an 'any' type.
==== tests/cases/compiler/controlFlowSelfReferentialLoop.ts (28 errors) ====
// Repro from #12319
function md5(string:string): void {
function FF(a,b,c,d,x,s,ac) {
~
!!! error TS7006: Parameter 'a' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'b' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'c' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'd' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 's' implicitly has an 'any' type.
~~
!!! error TS7006: Parameter 'ac' implicitly has an 'any' type.
return 0;
};
function GG(a,b,c,d,x,s,ac) {
~
!!! error TS7006: Parameter 'a' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'b' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'c' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'd' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 's' implicitly has an 'any' type.
~~
!!! error TS7006: Parameter 'ac' implicitly has an 'any' type.
return 0;
};
function HH(a,b,c,d,x,s,ac) {
~
!!! error TS7006: Parameter 'a' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'b' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'c' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'd' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 's' implicitly has an 'any' type.
~~
!!! error TS7006: Parameter 'ac' implicitly has an 'any' type.
return 0;
};
function II(a,b,c,d,x,s,ac) {
~
!!! error TS7006: Parameter 'a' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'b' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'c' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'd' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
~
!!! error TS7006: Parameter 's' implicitly has an 'any' type.
~~
!!! error TS7006: Parameter 'ac' implicitly has an 'any' type.
return 0;
};
var x=Array();
var k,AA,BB,CC,DD,a,b,c,d;
var S11=7, S12=12, S13=17, S14=22;
var S21=5, S22=9 , S23=14, S24=20;
var S31=4, S32=11, S33=16, S34=23;
var S41=6, S42=10, S43=15, S44=21;
x = [1];
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k=0;k<x.length;k+=16) {
AA=a; BB=b; CC=c; DD=d;
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
}
}
export default md5;
@@ -0,0 +1,207 @@
//// [controlFlowSelfReferentialLoop.ts]
// Repro from #12319
function md5(string:string): void {
function FF(a,b,c,d,x,s,ac) {
return 0;
};
function GG(a,b,c,d,x,s,ac) {
return 0;
};
function HH(a,b,c,d,x,s,ac) {
return 0;
};
function II(a,b,c,d,x,s,ac) {
return 0;
};
var x=Array();
var k,AA,BB,CC,DD,a,b,c,d;
var S11=7, S12=12, S13=17, S14=22;
var S21=5, S22=9 , S23=14, S24=20;
var S31=4, S32=11, S33=16, S34=23;
var S41=6, S42=10, S43=15, S44=21;
x = [1];
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k=0;k<x.length;k+=16) {
AA=a; BB=b; CC=c; DD=d;
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
}
}
export default md5;
//// [controlFlowSelfReferentialLoop.js]
// Repro from #12319
"use strict";
function md5(string) {
function FF(a, b, c, d, x, s, ac) {
return 0;
}
;
function GG(a, b, c, d, x, s, ac) {
return 0;
}
;
function HH(a, b, c, d, x, s, ac) {
return 0;
}
;
function II(a, b, c, d, x, s, ac) {
return 0;
}
;
var x = Array();
var k, AA, BB, CC, DD, a, b, c, d;
var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
x = [1];
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
for (k = 0; k < x.length; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
}
}
exports.__esModule = true;
exports["default"] = md5;
@@ -0,0 +1,39 @@
//// [exhaustiveSwitchWithWideningLiteralTypes.ts]
// Repro from #12529
class A {
readonly kind = "A"; // (property) A.kind: "A"
}
class B {
readonly kind = "B"; // (property) B.kind: "B"
}
function f(value: A | B): number {
switch(value.kind) {
case "A": return 0;
case "B": return 1;
}
}
//// [exhaustiveSwitchWithWideningLiteralTypes.js]
// Repro from #12529
var A = (function () {
function A() {
this.kind = "A"; // (property) A.kind: "A"
}
return A;
}());
var B = (function () {
function B() {
this.kind = "B"; // (property) B.kind: "B"
}
return B;
}());
function f(value) {
switch (value.kind) {
case "A": return 0;
case "B": return 1;
}
}
@@ -0,0 +1,33 @@
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
// Repro from #12529
class A {
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
readonly kind = "A"; // (property) A.kind: "A"
>kind : Symbol(A.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9))
}
class B {
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
readonly kind = "B"; // (property) B.kind: "B"
>kind : Symbol(B.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
}
function f(value: A | B): number {
>f : Symbol(f, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 9, 1))
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
switch(value.kind) {
>value.kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
>kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
case "A": return 0;
case "B": return 1;
}
}
@@ -0,0 +1,40 @@
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
// Repro from #12529
class A {
>A : A
readonly kind = "A"; // (property) A.kind: "A"
>kind : "A"
>"A" : "A"
}
class B {
>B : B
readonly kind = "B"; // (property) B.kind: "B"
>kind : "B"
>"B" : "B"
}
function f(value: A | B): number {
>f : (value: A | B) => number
>value : A | B
>A : A
>B : B
switch(value.kind) {
>value.kind : "A" | "B"
>value : A | B
>kind : "A" | "B"
case "A": return 0;
>"A" : "A"
>0 : 0
case "B": return 1;
>"B" : "B"
>1 : 1
}
}
@@ -1,7 +1,9 @@
tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(33,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(50,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
==== tests/cases/conformance/statements/for-inStatements/for-inStatements.ts (1 errors) ====
==== tests/cases/conformance/statements/for-inStatements/for-inStatements.ts (3 errors) ====
var aString: string;
for (aString in {}) { }
@@ -35,6 +37,8 @@ tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15):
for (var x in this.biz()) { }
for (var x in this.biz) { }
for (var x in this) { }
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
return null;
}
@@ -52,6 +56,8 @@ tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15):
for (var x in this.biz()) { }
for (var x in this.biz) { }
for (var x in this) { }
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
for (var x in super.biz) { }
for (var x in super.biz()) { }
@@ -9,13 +9,15 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(1
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(20,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(22,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(29,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(31,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(38,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(46,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(48,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(51,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(62,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts (15 errors) ====
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts (17 errors) ====
var aNumber: number;
for (aNumber in {}) { }
~~~~~~~
@@ -69,6 +71,8 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(6
!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
for (var x in this.biz) { }
for (var x in this) { }
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
return null;
}
@@ -90,6 +94,8 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(6
!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
for (var x in this.biz) { }
for (var x in this) { }
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'.
for (var x in super.biz) { }
for (var x in super.biz()) { }
@@ -8,7 +8,7 @@ function F<T>() {
>T : T
for (var a in expr) {
>a : string
>a : keyof T
>expr : T
}
}
@@ -22,7 +22,7 @@ class C {
>temp : () => void
for (var x in this) {
>x : string
>x : keyof this
>this : this
}
}
@@ -9,7 +9,7 @@ class C<T> {
>T : T
for (var p in x) {
>p : string
>p : keyof T
>x : T
}
}
@@ -1,8 +1,6 @@
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
@@ -19,7 +17,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ====
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (17 errors) ====
enum E { a }
var x: any;
@@ -42,11 +40,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra4 = a4 in x;
var ra5 = null in x;
~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra6 = undefined in x;
~~~~~~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra7 = E.a in x;
var ra8 = false in x;
~~~~~
@@ -58,6 +58,51 @@ function getValueAsString(value: IntersectionFail): string {
return '' + value.num;
}
return value.str;
}
// Repro from #12535
namespace enums {
export const enum A {
a1,
a2,
a3,
// ... elements omitted for the sake of clarity
a75,
a76,
a77,
}
export const enum B {
b1,
b2,
// ... elements omitted for the sake of clarity
b86,
b87,
}
export const enum C {
c1,
c2,
// ... elements omitted for the sake of clarity
c210,
c211,
}
export type Genre = A | B | C;
}
type Foo = {
genreId: enums.Genre;
};
type Bar = {
genreId: enums.Genre;
};
type FooBar = Foo & Bar;
function foo(so: any) {
const val = so as FooBar;
const isGenre = val.genreId;
return isGenre;
}
//// [intersectionTypeNormalization.js]
@@ -77,3 +122,8 @@ function getValueAsString(value) {
}
return value.str;
}
function foo(so) {
var val = so;
var isGenre = val.genreId;
return isGenre;
}
@@ -240,3 +240,113 @@ function getValueAsString(value: IntersectionFail): string {
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
}
// Repro from #12535
namespace enums {
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
export const enum A {
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
a1,
>a1 : Symbol(A.a1, Decl(intersectionTypeNormalization.ts, 64, 25))
a2,
>a2 : Symbol(A.a2, Decl(intersectionTypeNormalization.ts, 65, 11))
a3,
>a3 : Symbol(A.a3, Decl(intersectionTypeNormalization.ts, 66, 11))
// ... elements omitted for the sake of clarity
a75,
>a75 : Symbol(A.a75, Decl(intersectionTypeNormalization.ts, 67, 11))
a76,
>a76 : Symbol(A.a76, Decl(intersectionTypeNormalization.ts, 69, 12))
a77,
>a77 : Symbol(A.a77, Decl(intersectionTypeNormalization.ts, 70, 12))
}
export const enum B {
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
b1,
>b1 : Symbol(B.b1, Decl(intersectionTypeNormalization.ts, 73, 25))
b2,
>b2 : Symbol(B.b2, Decl(intersectionTypeNormalization.ts, 74, 11))
// ... elements omitted for the sake of clarity
b86,
>b86 : Symbol(B.b86, Decl(intersectionTypeNormalization.ts, 75, 11))
b87,
>b87 : Symbol(B.b87, Decl(intersectionTypeNormalization.ts, 77, 12))
}
export const enum C {
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
c1,
>c1 : Symbol(C.c1, Decl(intersectionTypeNormalization.ts, 80, 25))
c2,
>c2 : Symbol(C.c2, Decl(intersectionTypeNormalization.ts, 81, 11))
// ... elements omitted for the sake of clarity
c210,
>c210 : Symbol(C.c210, Decl(intersectionTypeNormalization.ts, 82, 11))
c211,
>c211 : Symbol(C.c211, Decl(intersectionTypeNormalization.ts, 84, 13))
}
export type Genre = A | B | C;
>Genre : Symbol(Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
}
type Foo = {
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
genreId: enums.Genre;
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12))
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
};
type Bar = {
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
genreId: enums.Genre;
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 94, 12))
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
};
type FooBar = Foo & Bar;
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
function foo(so: any) {
>foo : Symbol(foo, Decl(intersectionTypeNormalization.ts, 98, 24))
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
const val = so as FooBar;
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
const isGenre = val.genreId;
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
>val.genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
return isGenre;
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
}
@@ -244,3 +244,114 @@ function getValueAsString(value: IntersectionFail): string {
>value : { kind: "string"; str: string; } & ToString
>str : string
}
// Repro from #12535
namespace enums {
>enums : typeof enums
export const enum A {
>A : A
a1,
>a1 : A.a1
a2,
>a2 : A.a2
a3,
>a3 : A.a3
// ... elements omitted for the sake of clarity
a75,
>a75 : A.a75
a76,
>a76 : A.a76
a77,
>a77 : A.a77
}
export const enum B {
>B : B
b1,
>b1 : B.b1
b2,
>b2 : B.b2
// ... elements omitted for the sake of clarity
b86,
>b86 : B.b86
b87,
>b87 : B.b87
}
export const enum C {
>C : C
c1,
>c1 : C.c1
c2,
>c2 : C.c2
// ... elements omitted for the sake of clarity
c210,
>c210 : C.c210
c211,
>c211 : C.c211
}
export type Genre = A | B | C;
>Genre : Genre
>A : A
>B : B
>C : C
}
type Foo = {
>Foo : Foo
genreId: enums.Genre;
>genreId : enums.Genre
>enums : any
>Genre : enums.Genre
};
type Bar = {
>Bar : Bar
genreId: enums.Genre;
>genreId : enums.Genre
>enums : any
>Genre : enums.Genre
};
type FooBar = Foo & Bar;
>FooBar : FooBar
>Foo : Foo
>Bar : Bar
function foo(so: any) {
>foo : (so: any) => enums.Genre
>so : any
const val = so as FooBar;
>val : FooBar
>so as FooBar : FooBar
>so : any
>FooBar : FooBar
const isGenre = val.genreId;
>isGenre : enums.Genre
>val.genreId : enums.Genre
>val : FooBar
>genreId : enums.Genre
return isGenre;
>isGenre : enums.Genre
}
@@ -0,0 +1,10 @@
//// [intersectionTypeWithLeadingOperator.ts]
type A = & string;
type B =
& { foo: string }
& { bar: number };
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
//// [intersectionTypeWithLeadingOperator.js]
@@ -0,0 +1,20 @@
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
type A = & string;
>A : Symbol(A, Decl(intersectionTypeWithLeadingOperator.ts, 0, 0))
type B =
>B : Symbol(B, Decl(intersectionTypeWithLeadingOperator.ts, 0, 18))
& { foo: string }
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 2, 5))
& { bar: number };
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 3, 5))
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
>C : Symbol(C, Decl(intersectionTypeWithLeadingOperator.ts, 3, 20))
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 13))
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 26))
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 40))
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 53))
@@ -0,0 +1,20 @@
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
type A = & string;
>A : string
type B =
>B : B
& { foo: string }
>foo : string
& { bar: number };
>bar : number
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
>C : [{ foo: 1; } & { bar: 2; }, { foo: 3; } & { bar: 4; }]
>foo : 1
>bar : 2
>foo : 3
>bar : 4
@@ -1,6 +1,6 @@
tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(5,12): error TS2503: Cannot find namespace 'V'.
tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(11,12): error TS2503: Cannot find namespace 'C'.
tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(23,12): error TS2693: 'I' only refers to a type, but is being used as a value here.
tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(23,12): error TS2702: 'I' only refers to a type, but is being used as a namespace here.
==== tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts (3 errors) ====
@@ -32,5 +32,5 @@ tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIde
import i = I;
~
!!! error TS2693: 'I' only refers to a type, but is being used as a value here.
!!! error TS2702: 'I' only refers to a type, but is being used as a namespace here.
@@ -0,0 +1,11 @@
tests/cases/compiler/invalidUseOfTypeAsNamespace.ts(4,16): error TS2702: 'OhNo' only refers to a type, but is being used as a namespace here.
==== tests/cases/compiler/invalidUseOfTypeAsNamespace.ts (1 errors) ====
interface OhNo {
}
declare let y: OhNo.hello;
~~~~
!!! error TS2702: 'OhNo' only refers to a type, but is being used as a namespace here.
@@ -0,0 +1,8 @@
//// [invalidUseOfTypeAsNamespace.ts]
interface OhNo {
}
declare let y: OhNo.hello;
//// [invalidUseOfTypeAsNamespace.js]
@@ -0,0 +1,256 @@
//// [isomorphicMappedTypeInference.ts]
type Box<T> = {
value: T;
}
type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
}
function box<T>(x: T): Box<T> {
return { value: x };
}
function unbox<T>(x: Box<T>): T {
return x.value;
}
function boxify<T>(obj: T): Boxified<T> {
let result = {} as Boxified<T>;
for (let k in obj) {
result[k] = box(obj[k]);
}
return result;
}
function unboxify<T>(obj: Boxified<T>): T {
let result = {} as T;
for (let k in obj) {
result[k] = unbox(obj[k]);
}
return result;
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
for (let k in values) {
obj[k].value = values[k];
}
}
function f1() {
let v = {
a: 42,
b: "hello",
c: true
};
let b = boxify(v);
let x: number = b.a.value;
}
function f2() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
let v = unboxify(b);
let x: number = v.a;
}
function f3() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
assignBoxified(b, { c: false });
}
function f4() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
b = boxify(unboxify(b));
b = unboxify(boxify(b));
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
return obj;
}
function f5(s: string) {
let b = makeRecord({
a: box(42),
b: box("hello"),
c: box(true)
});
let v = unboxify(b);
let x: string | number | boolean = v.a;
}
function makeDictionary<T>(obj: { [x: string]: T }) {
return obj;
}
function f6(s: string) {
let b = makeDictionary({
a: box(42),
b: box("hello"),
c: box(true)
});
let v = unboxify(b);
let x: string | number | boolean = v[s];
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
type Foo = {
a?: number;
readonly b: string;
}
function f10(foo: Foo) {
let x = validate(foo); // { a: number, readonly b: string }
let y = clone(foo); // { a?: number, b: string }
let z = validateAndClone(foo); // { a: number, b: string }
}
//// [isomorphicMappedTypeInference.js]
function box(x) {
return { value: x };
}
function unbox(x) {
return x.value;
}
function boxify(obj) {
var result = {};
for (var k in obj) {
result[k] = box(obj[k]);
}
return result;
}
function unboxify(obj) {
var result = {};
for (var k in obj) {
result[k] = unbox(obj[k]);
}
return result;
}
function assignBoxified(obj, values) {
for (var k in values) {
obj[k].value = values[k];
}
}
function f1() {
var v = {
a: 42,
b: "hello",
c: true
};
var b = boxify(v);
var x = b.a.value;
}
function f2() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
var v = unboxify(b);
var x = v.a;
}
function f3() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
assignBoxified(b, { c: false });
}
function f4() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
b = boxify(unboxify(b));
b = unboxify(boxify(b));
}
function makeRecord(obj) {
return obj;
}
function f5(s) {
var b = makeRecord({
a: box(42),
b: box("hello"),
c: box(true)
});
var v = unboxify(b);
var x = v.a;
}
function makeDictionary(obj) {
return obj;
}
function f6(s) {
var b = makeDictionary({
a: box(42),
b: box("hello"),
c: box(true)
});
var v = unboxify(b);
var x = v[s];
}
function f10(foo) {
var x = validate(foo); // { a: number, readonly b: string }
var y = clone(foo); // { a?: number, b: string }
var z = validateAndClone(foo); // { a: number, b: string }
}
//// [isomorphicMappedTypeInference.d.ts]
declare type Box<T> = {
value: T;
};
declare type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
};
declare function box<T>(x: T): Box<T>;
declare function unbox<T>(x: Box<T>): T;
declare function boxify<T>(obj: T): Boxified<T>;
declare function unboxify<T>(obj: Boxified<T>): T;
declare function assignBoxified<T>(obj: Boxified<T>, values: T): void;
declare function f1(): void;
declare function f2(): void;
declare function f3(): void;
declare function f4(): void;
declare function makeRecord<T, K extends string>(obj: {
[P in K]: T;
}): {
[P in K]: T;
};
declare function f5(s: string): void;
declare function makeDictionary<T>(obj: {
[x: string]: T;
}): {
[x: string]: T;
};
declare function f6(s: string): void;
declare function validate<T>(obj: {
[P in keyof T]?: T[P];
}): T;
declare function clone<T>(obj: {
readonly [P in keyof T]: T[P];
}): T;
declare function validateAndClone<T>(obj: {
readonly [P in keyof T]?: T[P];
}): T;
declare type Foo = {
a?: number;
readonly b: string;
};
declare function f10(foo: Foo): void;
@@ -0,0 +1,395 @@
=== tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts ===
type Box<T> = {
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 1, 9))
value: T;
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 1, 9))
}
type Boxified<T> = {
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
[P in keyof T]: Box<T[P]>;
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 6, 5))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 6, 5))
}
function box<T>(x: T): Box<T> {
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 9, 16))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
return { value: x };
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 10, 12))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 9, 16))
}
function unbox<T>(x: Box<T>): T {
>unbox : Symbol(unbox, Decl(isomorphicMappedTypeInference.ts, 11, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 13, 18))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
return x.value;
>x.value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 13, 18))
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
}
function boxify<T>(obj: T): Boxified<T> {
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
let result = {} as Boxified<T>;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
for (let k in obj) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
result[k] = box(obj[k]);
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
}
return result;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
}
function unboxify<T>(obj: Boxified<T>): T {
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
let result = {} as T;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
for (let k in obj) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
result[k] = unbox(obj[k]);
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
>unbox : Symbol(unbox, Decl(isomorphicMappedTypeInference.ts, 11, 1))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
}
return result;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
>assignBoxified : Symbol(assignBoxified, Decl(isomorphicMappedTypeInference.ts, 31, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 33, 27))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
for (let k in values) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
obj[k].value = values[k];
>obj[k].value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 33, 27))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
}
}
function f1() {
>f1 : Symbol(f1, Decl(isomorphicMappedTypeInference.ts, 37, 1))
let v = {
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 40, 7))
a: 42,
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 40, 13))
b: "hello",
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 41, 14))
c: true
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 42, 19))
};
let b = boxify(v);
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 45, 7))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 40, 7))
let x: number = b.a.value;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 46, 7))
>b.a.value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>b.a : Symbol(a)
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 45, 7))
>a : Symbol(a)
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
}
function f2() {
>f2 : Symbol(f2, Decl(isomorphicMappedTypeInference.ts, 47, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 50, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 51, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 52, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 55, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 50, 7))
let x: number = v.a;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 56, 7))
>v.a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 55, 7))
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
}
function f3() {
>f3 : Symbol(f3, Decl(isomorphicMappedTypeInference.ts, 57, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 60, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 60, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 61, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 62, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
assignBoxified(b, { c: false });
>assignBoxified : Symbol(assignBoxified, Decl(isomorphicMappedTypeInference.ts, 31, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 60, 7))
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 65, 23))
}
function f4() {
>f4 : Symbol(f4, Decl(isomorphicMappedTypeInference.ts, 66, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 69, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 70, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 71, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
b = boxify(unboxify(b));
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
b = unboxify(boxify(b));
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
>makeRecord : Symbol(makeRecord, Decl(isomorphicMappedTypeInference.ts, 76, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 78, 20))
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 78, 22))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 78, 41))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 78, 49))
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 78, 22))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 78, 20))
return obj;
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 78, 41))
}
function f5(s: string) {
>f5 : Symbol(f5, Decl(isomorphicMappedTypeInference.ts, 80, 1))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 82, 12))
let b = makeRecord({
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 83, 7))
>makeRecord : Symbol(makeRecord, Decl(isomorphicMappedTypeInference.ts, 76, 1))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 83, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 84, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 85, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
});
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 88, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 83, 7))
let x: string | number | boolean = v.a;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 89, 7))
>v.a : Symbol(a)
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 88, 7))
>a : Symbol(a)
}
function makeDictionary<T>(obj: { [x: string]: T }) {
>makeDictionary : Symbol(makeDictionary, Decl(isomorphicMappedTypeInference.ts, 90, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 92, 24))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 92, 27))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 92, 35))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 92, 24))
return obj;
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 92, 27))
}
function f6(s: string) {
>f6 : Symbol(f6, Decl(isomorphicMappedTypeInference.ts, 94, 1))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 96, 12))
let b = makeDictionary({
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 97, 7))
>makeDictionary : Symbol(makeDictionary, Decl(isomorphicMappedTypeInference.ts, 90, 1))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 97, 28))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 98, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 99, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
});
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 102, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 97, 7))
let x: string | number | boolean = v[s];
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 103, 7))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 102, 7))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 96, 12))
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 106, 29))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 107, 26))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 108, 37))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
type Foo = {
>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81))
a?: number;
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 110, 12))
readonly b: string;
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 111, 15))
}
function f10(foo: Foo) {
>f10 : Symbol(f10, Decl(isomorphicMappedTypeInference.ts, 113, 1))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81))
let x = validate(foo); // { a: number, readonly b: string }
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 116, 7))
>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
let y = clone(foo); // { a?: number, b: string }
>y : Symbol(y, Decl(isomorphicMappedTypeInference.ts, 117, 7))
>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
let z = validateAndClone(foo); // { a: number, b: string }
>z : Symbol(z, Decl(isomorphicMappedTypeInference.ts, 118, 7))
>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
}
@@ -0,0 +1,469 @@
=== tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts ===
type Box<T> = {
>Box : Box<T>
>T : T
value: T;
>value : T
>T : T
}
type Boxified<T> = {
>Boxified : Boxified<T>
>T : T
[P in keyof T]: Box<T[P]>;
>P : P
>T : T
>Box : Box<T>
>T : T
>P : P
}
function box<T>(x: T): Box<T> {
>box : <T>(x: T) => Box<T>
>T : T
>x : T
>T : T
>Box : Box<T>
>T : T
return { value: x };
>{ value: x } : { value: T; }
>value : T
>x : T
}
function unbox<T>(x: Box<T>): T {
>unbox : <T>(x: Box<T>) => T
>T : T
>x : Box<T>
>Box : Box<T>
>T : T
>T : T
return x.value;
>x.value : T
>x : Box<T>
>value : T
}
function boxify<T>(obj: T): Boxified<T> {
>boxify : <T>(obj: T) => Boxified<T>
>T : T
>obj : T
>T : T
>Boxified : Boxified<T>
>T : T
let result = {} as Boxified<T>;
>result : Boxified<T>
>{} as Boxified<T> : Boxified<T>
>{} : {}
>Boxified : Boxified<T>
>T : T
for (let k in obj) {
>k : keyof T
>obj : T
result[k] = box(obj[k]);
>result[k] = box(obj[k]) : Box<T[keyof T]>
>result[k] : Box<T[keyof T]>
>result : Boxified<T>
>k : keyof T
>box(obj[k]) : Box<T[keyof T]>
>box : <T>(x: T) => Box<T>
>obj[k] : T[keyof T]
>obj : T
>k : keyof T
}
return result;
>result : Boxified<T>
}
function unboxify<T>(obj: Boxified<T>): T {
>unboxify : <T>(obj: Boxified<T>) => T
>T : T
>obj : Boxified<T>
>Boxified : Boxified<T>
>T : T
>T : T
let result = {} as T;
>result : T
>{} as T : T
>{} : {}
>T : T
for (let k in obj) {
>k : keyof T
>obj : Boxified<T>
result[k] = unbox(obj[k]);
>result[k] = unbox(obj[k]) : T[keyof T]
>result[k] : T[keyof T]
>result : T
>k : keyof T
>unbox(obj[k]) : T[keyof T]
>unbox : <T>(x: Box<T>) => T
>obj[k] : Box<T[keyof T]>
>obj : Boxified<T>
>k : keyof T
}
return result;
>result : T
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
>assignBoxified : <T>(obj: Boxified<T>, values: T) => void
>T : T
>obj : Boxified<T>
>Boxified : Boxified<T>
>T : T
>values : T
>T : T
for (let k in values) {
>k : keyof T
>values : T
obj[k].value = values[k];
>obj[k].value = values[k] : T[keyof T]
>obj[k].value : T[keyof T]
>obj[k] : Box<T[keyof T]>
>obj : Boxified<T>
>k : keyof T
>value : T[keyof T]
>values[k] : T[keyof T]
>values : T
>k : keyof T
}
}
function f1() {
>f1 : () => void
let v = {
>v : { a: number; b: string; c: boolean; }
>{ a: 42, b: "hello", c: true } : { a: number; b: string; c: boolean; }
a: 42,
>a : number
>42 : 42
b: "hello",
>b : string
>"hello" : "hello"
c: true
>c : boolean
>true : true
};
let b = boxify(v);
>b : Boxified<{ a: number; b: string; c: boolean; }>
>boxify(v) : Boxified<{ a: number; b: string; c: boolean; }>
>boxify : <T>(obj: T) => Boxified<T>
>v : { a: number; b: string; c: boolean; }
let x: number = b.a.value;
>x : number
>b.a.value : number
>b.a : Box<number>
>b : Boxified<{ a: number; b: string; c: boolean; }>
>a : Box<number>
>value : number
}
function f2() {
>f2 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
let v = unboxify(b);
>v : { a: number; b: string; c: boolean; }
>unboxify(b) : { a: number; b: string; c: boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
let x: number = v.a;
>x : number
>v.a : number
>v : { a: number; b: string; c: boolean; }
>a : number
}
function f3() {
>f3 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
assignBoxified(b, { c: false });
>assignBoxified(b, { c: false }) : void
>assignBoxified : <T>(obj: Boxified<T>, values: T) => void
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ c: false } : { c: false; }
>c : boolean
>false : false
}
function f4() {
>f4 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
b = boxify(unboxify(b));
>b = boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>boxify : <T>(obj: T) => Boxified<T>
>unboxify(b) : { a: number; b: string; c: boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
b = unboxify(boxify(b));
>b = unboxify(boxify(b)) : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>unboxify(boxify(b)) : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>unboxify : <T>(obj: Boxified<T>) => T
>boxify(b) : Boxified<{ a: Box<number>; b: Box<string>; c: Box<boolean>; }>
>boxify : <T>(obj: T) => Boxified<T>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
>makeRecord : <T, K extends string>(obj: { [P in K]: T; }) => { [P in K]: T; }
>T : T
>K : K
>obj : { [P in K]: T; }
>P : P
>K : K
>T : T
return obj;
>obj : { [P in K]: T; }
}
function f5(s: string) {
>f5 : (s: string) => void
>s : string
let b = makeRecord({
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
>makeRecord({ a: box(42), b: box("hello"), c: box(true) }) : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
>makeRecord : <T, K extends string>(obj: { [P in K]: T; }) => { [P in K]: T; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
});
let v = unboxify(b);
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v.a;
>x : string | number | boolean
>v.a : string | number | boolean
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>a : string | number | boolean
}
function makeDictionary<T>(obj: { [x: string]: T }) {
>makeDictionary : <T>(obj: { [x: string]: T; }) => { [x: string]: T; }
>T : T
>obj : { [x: string]: T; }
>x : string
>T : T
return obj;
>obj : { [x: string]: T; }
}
function f6(s: string) {
>f6 : (s: string) => void
>s : string
let b = makeDictionary({
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
>makeDictionary({ a: box(42), b: box("hello"), c: box(true) }) : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
>makeDictionary : <T>(obj: { [x: string]: T; }) => { [x: string]: T; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
});
let v = unboxify(b);
>v : { [x: string]: string | number | boolean; }
>unboxify(b) : { [x: string]: string | number | boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v[s];
>x : string | number | boolean
>v[s] : string | number | boolean
>v : { [x: string]: string | number | boolean; }
>s : string
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>T : T
>obj : { [P in keyof T]?: T[P] | undefined; }
>P : P
>T : T
>T : T
>P : P
>T : T
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>T : T
>obj : { readonly [P in keyof T]: T[P]; }
>P : P
>T : T
>T : T
>P : P
>T : T
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>T : T
>obj : { readonly [P in keyof T]?: T[P] | undefined; }
>P : P
>T : T
>T : T
>P : P
>T : T
type Foo = {
>Foo : Foo
a?: number;
>a : number | undefined
readonly b: string;
>b : string
}
function f10(foo: Foo) {
>f10 : (foo: Foo) => void
>foo : Foo
>Foo : Foo
let x = validate(foo); // { a: number, readonly b: string }
>x : { a: number; readonly b: string; }
>validate(foo) : { a: number; readonly b: string; }
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
let y = clone(foo); // { a?: number, b: string }
>y : { a?: number | undefined; b: string; }
>clone(foo) : { a?: number | undefined; b: string; }
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>foo : Foo
let z = validateAndClone(foo); // { a: number, b: string }
>z : { a: number; b: string; }
>validateAndClone(foo) : { a: number; b: string; }
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
}
@@ -0,0 +1,27 @@
//// [index.tsx]
import "./jsx";
var skate: any;
const React = { createElement: skate.h };
class Component {
renderCallback() {
return <div>test</div>;
}
};
//// [index.js]
"use strict";
require("./jsx");
var skate;
var React = { createElement: skate.h };
var Component = (function () {
function Component() {
}
Component.prototype.renderCallback = function () {
return skate.h("div", null, "test");
};
return Component;
}());
;
@@ -0,0 +1,23 @@
=== tests/cases/compiler/index.tsx ===
import "./jsx";
var skate: any;
>skate : Symbol(skate, Decl(index.tsx, 3, 3))
const React = { createElement: skate.h };
>React : Symbol(React, Decl(index.tsx, 4, 5))
>createElement : Symbol(createElement, Decl(index.tsx, 4, 15))
>skate : Symbol(skate, Decl(index.tsx, 3, 3))
class Component {
>Component : Symbol(Component, Decl(index.tsx, 4, 41))
renderCallback() {
>renderCallback : Symbol(Component.renderCallback, Decl(index.tsx, 6, 17))
return <div>test</div>;
>div : Symbol(unknown)
>div : Symbol(unknown)
}
};
@@ -0,0 +1,27 @@
=== tests/cases/compiler/index.tsx ===
import "./jsx";
var skate: any;
>skate : any
const React = { createElement: skate.h };
>React : { createElement: any; }
>{ createElement: skate.h } : { createElement: any; }
>createElement : any
>skate.h : any
>skate : any
>h : any
class Component {
>Component : Component
renderCallback() {
>renderCallback : () => any
return <div>test</div>;
><div>test</div> : any
>div : any
>div : any
}
};
@@ -0,0 +1,81 @@
//// [keyofAndForIn.ts]
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
const b = k in obj;
let k1: keyof T;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
//// [keyofAndForIn.js]
// Repro from #12513
function f1(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
function f2(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
function f3(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
//// [keyofAndForIn.d.ts]
declare function f1<K extends string, T>(obj: {
[P in K]: T;
}, k: K): void;
declare function f2<T>(obj: {
[P in keyof T]: T[P];
}, k: keyof T): void;
declare function f3<T, K extends keyof T>(obj: {
[P in K]: T[P];
}, k: K): void;
@@ -0,0 +1,125 @@
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
>f1 : Symbol(f1, Decl(keyofAndForIn.ts, 0, 0))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>P : Symbol(P, Decl(keyofAndForIn.ts, 3, 41))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 4, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let k1: K;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 7, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 10, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
>f2 : Symbol(f2, Decl(keyofAndForIn.ts, 12, 1))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 15, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let k1: keyof T;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 18, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 21, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
>f3 : Symbol(f3, Decl(keyofAndForIn.ts, 23, 1))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 26, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let k1: K;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 29, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 32, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
}
}
@@ -0,0 +1,134 @@
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
>f1 : <K extends string, T>(obj: { [P in K]: T; }, k: K) => void
>K : K
>T : T
>obj : { [P in K]: T; }
>P : P
>K : K
>T : T
>k : K
>K : K
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : K
>obj : { [P in K]: T; }
let k1: K;
>k1 : K
>K : K
for (k1 in obj) {
>k1 : K
>obj : { [P in K]: T; }
let x1 = obj[k1];
>x1 : T
>obj[k1] : T
>obj : { [P in K]: T; }
>k1 : K
}
for (let k2 in obj) {
>k2 : K
>obj : { [P in K]: T; }
let x2 = obj[k2];
>x2 : T
>obj[k2] : T
>obj : { [P in K]: T; }
>k2 : K
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
>f2 : <T>(obj: { [P in keyof T]: T[P]; }, k: keyof T) => void
>T : T
>obj : { [P in keyof T]: T[P]; }
>P : P
>T : T
>T : T
>P : P
>k : keyof T
>T : T
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : keyof T
>obj : { [P in keyof T]: T[P]; }
let k1: keyof T;
>k1 : keyof T
>T : T
for (k1 in obj) {
>k1 : keyof T
>obj : { [P in keyof T]: T[P]; }
let x1 = obj[k1];
>x1 : T[keyof T]
>obj[k1] : T[keyof T]
>obj : { [P in keyof T]: T[P]; }
>k1 : keyof T
}
for (let k2 in obj) {
>k2 : keyof T
>obj : { [P in keyof T]: T[P]; }
let x2 = obj[k2];
>x2 : T[keyof T]
>obj[k2] : T[keyof T]
>obj : { [P in keyof T]: T[P]; }
>k2 : keyof T
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
>f3 : <T, K extends keyof T>(obj: { [P in K]: T[P]; }, k: K) => void
>T : T
>K : K
>T : T
>obj : { [P in K]: T[P]; }
>P : P
>K : K
>T : T
>P : P
>k : K
>K : K
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : K
>obj : { [P in K]: T[P]; }
let k1: K;
>k1 : K
>K : K
for (k1 in obj) {
>k1 : K
>obj : { [P in K]: T[P]; }
let x1 = obj[k1];
>x1 : T[K]
>obj[k1] : T[K]
>obj : { [P in K]: T[P]; }
>k1 : K
}
for (let k2 in obj) {
>k2 : K
>obj : { [P in K]: T[P]; }
let x2 = obj[k2];
>x2 : T[K]
>obj[k2] : T[K]
>obj : { [P in K]: T[P]; }
>k2 : K
}
}
@@ -21,11 +21,12 @@ class Options {
}
type Dictionary<T> = { [x: string]: T };
type NumericallyIndexed<T> = { [x: number]: T };
const enum E { A, B, C }
type K00 = keyof any; // string | number
type K01 = keyof string; // number | "toString" | "charAt" | ...
type K00 = keyof any; // string
type K01 = keyof string; // "toString" | "charAt" | ...
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
type K03 = keyof boolean; // "valueOf"
type K04 = keyof void; // never
@@ -34,19 +35,20 @@ type K06 = keyof null; // never
type K07 = keyof never; // never
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string | number
type K11 = keyof Shape[]; // "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string
type K13 = keyof {}; // never
type K14 = keyof Object; // "constructor" | "toString" | ...
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
type K17 = keyof (Shape | Item); // "name"
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
type K19 = keyof NumericallyIndexed<Shape> // never
type KeyOf<T> = keyof T;
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
type K21 = KeyOf<Dictionary<Shape>>; // string | number
type K21 = KeyOf<Dictionary<Shape>>; // string
type NAME = "name";
type WIDTH_OR_HEIGHT = "width" | "height";
@@ -95,22 +97,18 @@ function f10(shape: Shape) {
function f11(a: Shape[]) {
let len = getProperty(a, "length"); // number
let shape = getProperty(a, 1000); // Shape
setProperty(a, 1000, getProperty(a, 1001));
setProperty(a, "length", len);
}
function f12(t: [Shape, boolean]) {
let len = getProperty(t, "length");
let s1 = getProperty(t, 0); // Shape
let s2 = getProperty(t, "0"); // Shape
let b1 = getProperty(t, 1); // boolean
let b2 = getProperty(t, "1"); // boolean
let x1 = getProperty(t, 2); // Shape | boolean
}
function f13(foo: any, bar: any) {
let x = getProperty(foo, "x"); // any
let y = getProperty(foo, 100); // any
let y = getProperty(foo, "100"); // any
let z = getProperty(foo, bar); // any
}
@@ -181,6 +179,46 @@ function f40(c: C) {
let z: Z = c["z"];
}
function f50<T>(k: keyof T, s: string) {
const x1 = s as keyof T;
const x2 = k as string;
}
function f51<T, K extends keyof T>(k: K, s: string) {
const x1 = s as keyof T;
const x2 = k as string;
}
function f52<T>(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) {
const x1 = obj[s];
const x2 = obj[n];
const x3 = obj[k];
}
function f53<T, K extends keyof T>(obj: { [x: string]: boolean }, k: K, s: string, n: number) {
const x1 = obj[s];
const x2 = obj[n];
const x3 = obj[k];
}
function f54<T>(obj: T, key: keyof T) {
for (let s in obj[key]) {
}
const b = "foo" in obj[key];
}
function f55<T, K extends keyof T>(obj: T, key: K) {
for (let s in obj[key]) {
}
const b = "foo" in obj[key];
}
function f60<T>(source: T, target: T) {
for (let k in source) {
target[k] = source[k];
}
}
// Repros from #12011
class Base {
@@ -211,7 +249,8 @@ class OtherPerson {
getParts() {
return getProperty(this, "parts")
}
}
}
//// [keyofAndIndexedAccess.js]
var __extends = (this && this.__extends) || function (d, b) {
@@ -257,20 +296,16 @@ function f10(shape) {
}
function f11(a) {
var len = getProperty(a, "length"); // number
var shape = getProperty(a, 1000); // Shape
setProperty(a, 1000, getProperty(a, 1001));
setProperty(a, "length", len);
}
function f12(t) {
var len = getProperty(t, "length");
var s1 = getProperty(t, 0); // Shape
var s2 = getProperty(t, "0"); // Shape
var b1 = getProperty(t, 1); // boolean
var b2 = getProperty(t, "1"); // boolean
var x1 = getProperty(t, 2); // Shape | boolean
}
function f13(foo, bar) {
var x = getProperty(foo, "x"); // any
var y = getProperty(foo, 100); // any
var y = getProperty(foo, "100"); // any
var z = getProperty(foo, bar); // any
}
var Component = (function () {
@@ -329,6 +364,39 @@ function f40(c) {
var y = c["y"];
var z = c["z"];
}
function f50(k, s) {
var x1 = s;
var x2 = k;
}
function f51(k, s) {
var x1 = s;
var x2 = k;
}
function f52(obj, k, s, n) {
var x1 = obj[s];
var x2 = obj[n];
var x3 = obj[k];
}
function f53(obj, k, s, n) {
var x1 = obj[s];
var x2 = obj[n];
var x3 = obj[k];
}
function f54(obj, key) {
for (var s in obj[key]) {
}
var b = "foo" in obj[key];
}
function f55(obj, key) {
for (var s in obj[key]) {
}
var b = "foo" in obj[key];
}
function f60(source, target) {
for (var k in source) {
target[k] = source[k];
}
}
// Repros from #12011
var Base = (function () {
function Base() {
@@ -384,6 +452,9 @@ declare class Options {
declare type Dictionary<T> = {
[x: string]: T;
};
declare type NumericallyIndexed<T> = {
[x: number]: T;
};
declare const enum E {
A = 0,
B = 1,
@@ -406,6 +477,7 @@ declare type K15 = keyof E;
declare type K16 = keyof [string, number];
declare type K17 = keyof (Shape | Item);
declare type K18 = keyof (Shape & Item);
declare type K19 = keyof NumericallyIndexed<Shape>;
declare type KeyOf<T> = keyof T;
declare type K20 = KeyOf<Shape>;
declare type K21 = KeyOf<Dictionary<Shape>>;
@@ -454,6 +526,17 @@ declare class C {
private z;
}
declare function f40(c: C): void;
declare function f50<T>(k: keyof T, s: string): void;
declare function f51<T, K extends keyof T>(k: K, s: string): void;
declare function f52<T>(obj: {
[x: string]: boolean;
}, k: keyof T, s: string, n: number): void;
declare function f53<T, K extends keyof T>(obj: {
[x: string]: boolean;
}, k: K, s: string, n: number): void;
declare function f54<T>(obj: T, key: keyof T): void;
declare function f55<T, K extends keyof T>(obj: T, key: K): void;
declare function f60<T>(source: T, target: T): void;
declare class Base {
get<K extends keyof this>(prop: K): this[K];
set<K extends keyof this>(prop: K, value: this[K]): void;
File diff suppressed because it is too large Load Diff
@@ -47,17 +47,23 @@ type Dictionary<T> = { [x: string]: T };
>x : string
>T : T
type NumericallyIndexed<T> = { [x: number]: T };
>NumericallyIndexed : NumericallyIndexed<T>
>T : T
>x : number
>T : T
const enum E { A, B, C }
>E : E
>A : E.A
>B : E.B
>C : E.C
type K00 = keyof any; // string | number
>K00 : string | number
type K00 = keyof any; // string
>K00 : string
type K01 = keyof string; // number | "toString" | "charAt" | ...
>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf"
type K01 = keyof string; // "toString" | "charAt" | ...
>K01 : "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf"
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
>K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
@@ -82,12 +88,12 @@ type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
>K10 : "name" | "width" | "height" | "visible"
>Shape : Shape
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
>K11 : number | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K11 = keyof Shape[]; // "length" | "toString" | ...
>K11 : "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>Shape : Shape
type K12 = keyof Dictionary<Shape>; // string | number
>K12 : string | number
type K12 = keyof Dictionary<Shape>; // string
>K12 : string
>Dictionary : Dictionary<T>
>Shape : Shape
@@ -102,8 +108,8 @@ type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
>K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
>E : E
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
>K16 : number | "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
>K16 : "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K17 = keyof (Shape | Item); // "name"
>K17 : "name"
@@ -115,6 +121,11 @@ type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "
>Shape : Shape
>Item : Item
type K19 = keyof NumericallyIndexed<Shape> // never
>K19 : never
>NumericallyIndexed : NumericallyIndexed<T>
>Shape : Shape
type KeyOf<T> = keyof T;
>KeyOf : keyof T
>T : T
@@ -125,8 +136,8 @@ type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
>KeyOf : keyof T
>Shape : Shape
type K21 = KeyOf<Dictionary<Shape>>; // string | number
>K21 : string | number
type K21 = KeyOf<Dictionary<Shape>>; // string
>K21 : string
>KeyOf : keyof T
>Dictionary : Dictionary<T>
>Shape : Shape
@@ -328,22 +339,12 @@ function f11(a: Shape[]) {
>a : Shape[]
>"length" : "length"
let shape = getProperty(a, 1000); // Shape
>shape : Shape
>getProperty(a, 1000) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>a : Shape[]
>1000 : 1000
setProperty(a, 1000, getProperty(a, 1001));
>setProperty(a, 1000, getProperty(a, 1001)) : void
setProperty(a, "length", len);
>setProperty(a, "length", len) : void
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>a : Shape[]
>1000 : 1000
>getProperty(a, 1001) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>a : Shape[]
>1001 : 1001
>"length" : "length"
>len : number
}
function f12(t: [Shape, boolean]) {
@@ -358,13 +359,6 @@ function f12(t: [Shape, boolean]) {
>t : [Shape, boolean]
>"length" : "length"
let s1 = getProperty(t, 0); // Shape
>s1 : Shape
>getProperty(t, 0) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>0 : 0
let s2 = getProperty(t, "0"); // Shape
>s2 : Shape
>getProperty(t, "0") : Shape
@@ -372,26 +366,12 @@ function f12(t: [Shape, boolean]) {
>t : [Shape, boolean]
>"0" : "0"
let b1 = getProperty(t, 1); // boolean
>b1 : boolean
>getProperty(t, 1) : boolean
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>1 : 1
let b2 = getProperty(t, "1"); // boolean
>b2 : boolean
>getProperty(t, "1") : boolean
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>"1" : "1"
let x1 = getProperty(t, 2); // Shape | boolean
>x1 : boolean | Shape
>getProperty(t, 2) : boolean | Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>2 : 2
}
function f13(foo: any, bar: any) {
@@ -406,12 +386,12 @@ function f13(foo: any, bar: any) {
>foo : any
>"x" : "x"
let y = getProperty(foo, 100); // any
let y = getProperty(foo, "100"); // any
>y : any
>getProperty(foo, 100) : any
>getProperty(foo, "100") : any
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>foo : any
>100 : 100
>"100" : "100"
let z = getProperty(foo, bar); // any
>z : any
@@ -737,6 +717,177 @@ function f40(c: C) {
>"z" : "z"
}
function f50<T>(k: keyof T, s: string) {
>f50 : <T>(k: keyof T, s: string) => void
>T : T
>k : keyof T
>T : T
>s : string
const x1 = s as keyof T;
>x1 : keyof T
>s as keyof T : keyof T
>s : string
>T : T
const x2 = k as string;
>x2 : string
>k as string : string
>k : keyof T
}
function f51<T, K extends keyof T>(k: K, s: string) {
>f51 : <T, K extends keyof T>(k: K, s: string) => void
>T : T
>K : K
>T : T
>k : K
>K : K
>s : string
const x1 = s as keyof T;
>x1 : keyof T
>s as keyof T : keyof T
>s : string
>T : T
const x2 = k as string;
>x2 : string
>k as string : string
>k : K
}
function f52<T>(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) {
>f52 : <T>(obj: { [x: string]: boolean; }, k: keyof T, s: string, n: number) => void
>T : T
>obj : { [x: string]: boolean; }
>x : string
>k : keyof T
>T : T
>s : string
>n : number
const x1 = obj[s];
>x1 : boolean
>obj[s] : boolean
>obj : { [x: string]: boolean; }
>s : string
const x2 = obj[n];
>x2 : boolean
>obj[n] : boolean
>obj : { [x: string]: boolean; }
>n : number
const x3 = obj[k];
>x3 : boolean
>obj[k] : boolean
>obj : { [x: string]: boolean; }
>k : keyof T
}
function f53<T, K extends keyof T>(obj: { [x: string]: boolean }, k: K, s: string, n: number) {
>f53 : <T, K extends keyof T>(obj: { [x: string]: boolean; }, k: K, s: string, n: number) => void
>T : T
>K : K
>T : T
>obj : { [x: string]: boolean; }
>x : string
>k : K
>K : K
>s : string
>n : number
const x1 = obj[s];
>x1 : boolean
>obj[s] : boolean
>obj : { [x: string]: boolean; }
>s : string
const x2 = obj[n];
>x2 : boolean
>obj[n] : boolean
>obj : { [x: string]: boolean; }
>n : number
const x3 = obj[k];
>x3 : { [x: string]: boolean; }[K]
>obj[k] : { [x: string]: boolean; }[K]
>obj : { [x: string]: boolean; }
>k : K
}
function f54<T>(obj: T, key: keyof T) {
>f54 : <T>(obj: T, key: keyof T) => void
>T : T
>obj : T
>T : T
>key : keyof T
>T : T
for (let s in obj[key]) {
>s : string
>obj[key] : T[keyof T]
>obj : T
>key : keyof T
}
const b = "foo" in obj[key];
>b : boolean
>"foo" in obj[key] : boolean
>"foo" : "foo"
>obj[key] : T[keyof T]
>obj : T
>key : keyof T
}
function f55<T, K extends keyof T>(obj: T, key: K) {
>f55 : <T, K extends keyof T>(obj: T, key: K) => void
>T : T
>K : K
>T : T
>obj : T
>T : T
>key : K
>K : K
for (let s in obj[key]) {
>s : string
>obj[key] : T[K]
>obj : T
>key : K
}
const b = "foo" in obj[key];
>b : boolean
>"foo" in obj[key] : boolean
>"foo" : "foo"
>obj[key] : T[K]
>obj : T
>key : K
}
function f60<T>(source: T, target: T) {
>f60 : <T>(source: T, target: T) => void
>T : T
>source : T
>T : T
>target : T
>T : T
for (let k in source) {
>k : keyof T
>source : T
target[k] = source[k];
>target[k] = source[k] : T[keyof T]
>target[k] : T[keyof T]
>target : T
>k : keyof T
>source[k] : T[keyof T]
>source : T
>k : keyof T
}
}
// Repros from #12011
class Base {
@@ -830,3 +981,4 @@ class OtherPerson {
>"parts" : "parts"
}
}
@@ -0,0 +1,32 @@
tests/cases/compiler/keyofIsLiteralContexualType.ts(5,9): error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
Type '"c"' is not assignable to type '"a" | "b"'.
Type '"c"' is not assignable to type 'keyof T'.
Type '"c"' is not assignable to type '"a" | "b"'.
tests/cases/compiler/keyofIsLiteralContexualType.ts(13,11): error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
==== tests/cases/compiler/keyofIsLiteralContexualType.ts (2 errors) ====
// keyof T is a literal contextual type
function foo<T extends { a: string, b: string }>() {
let a: (keyof T)[] = ["a", "b"];
let b: (keyof T)[] = ["a", "b", "c"];
~
!!! error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
!!! error TS2322: Type '"c"' is not assignable to type 'keyof T'.
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
}
// Repro from #12455
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
let b = x.b; // Error
~
!!! error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
@@ -0,0 +1,23 @@
//// [keyofIsLiteralContexualType.ts]
// keyof T is a literal contextual type
function foo<T extends { a: string, b: string }>() {
let a: (keyof T)[] = ["a", "b"];
let b: (keyof T)[] = ["a", "b", "c"];
}
// Repro from #12455
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
let b = x.b; // Error
//// [keyofIsLiteralContexualType.js]
// keyof T is a literal contextual type
function foo() {
var a = ["a", "b"];
var b = ["a", "b", "c"];
}
var x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
var b = x.b; // Error
@@ -1,29 +1,28 @@
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(20,20): error TS2313: Type parameter 'P' has a circular constraint.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(21,20): error TS2322: Type 'Date' is not assignable to type 'string | number'.
Type 'Date' is not assignable to type 'number'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(22,19): error TS2344: Type 'Date' does not satisfy the constraint 'string | number'.
Type 'Date' is not assignable to type 'number'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(25,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(26,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(21,20): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(22,20): error TS2322: Type 'Date' is not assignable to type 'string'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(23,19): error TS2344: Type 'Date' does not satisfy the constraint 'string'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(26,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(27,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
Type '"foo"' is not assignable to type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(28,24): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(29,24): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
Type '"x"' is not assignable to type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(30,24): error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(33,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(31,24): error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(34,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
Type 'T' is not assignable to type '"visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(37,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(38,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
Type 'string | number' is not assignable to type '"name" | "width" | "height" | "visible"'.
Type 'string' is not assignable to type '"name" | "width" | "height" | "visible"'.
Type 'T' is not assignable to type '"visible"'.
Type 'string | number' is not assignable to type '"visible"'.
Type 'string' is not assignable to type '"visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(59,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(61,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(66,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(61,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(62,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'.
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (13 errors) ====
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (14 errors) ====
interface Shape {
name: string;
@@ -46,14 +45,15 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(66,9): error TS2403: Su
type T00 = { [P in P]: string }; // Error
~
!!! error TS2313: Type parameter 'P' has a circular constraint.
type T01 = { [P in Date]: number }; // Error
type T01 = { [P in number]: string }; // Error
~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
type T02 = { [P in Date]: number }; // Error
~~~~
!!! error TS2322: Type 'Date' is not assignable to type 'string | number'.
!!! error TS2322: Type 'Date' is not assignable to type 'number'.
type T02 = Record<Date, number>; // Error
!!! error TS2322: Type 'Date' is not assignable to type 'string'.
type T03 = Record<Date, number>; // Error
~~~~
!!! error TS2344: Type 'Date' does not satisfy the constraint 'string | number'.
!!! error TS2344: Type 'Date' is not assignable to type 'number'.
!!! error TS2344: Type 'Date' does not satisfy the constraint 'string'.
type T10 = Pick<Shape, "name">;
type T11 = Pick<Shape, "foo">; // Error
@@ -112,13 +112,13 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(66,9): error TS2403: Su
var x: { [P in keyof T]: T[P] };
var x: { [P in keyof T]?: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'.
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'.
var x: { readonly [P in keyof T]: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'.
var x: { readonly [P in keyof T]?: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'.
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'.
}
function f12<T>() {
@@ -19,8 +19,9 @@ interface Point {
// Constraint checking
type T00 = { [P in P]: string }; // Error
type T01 = { [P in Date]: number }; // Error
type T02 = Record<Date, number>; // Error
type T01 = { [P in number]: string }; // Error
type T02 = { [P in Date]: number }; // Error
type T03 = Record<Date, number>; // Error
type T10 = Pick<Shape, "name">;
type T11 = Pick<Shape, "foo">; // Error
@@ -116,9 +117,12 @@ declare type T00 = {
[P in P]: string;
};
declare type T01 = {
[P in number]: string;
};
declare type T02 = {
[P in Date]: number;
};
declare type T02 = Record<Date, number>;
declare type T03 = Record<Date, number>;
declare type T10 = Pick<Shape, "name">;
declare type T11 = Pick<Shape, "foo">;
declare type T12 = Pick<Shape, "name" | "foo">;
@@ -0,0 +1,12 @@
//// [mappedTypeInferenceCircularity.ts]
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
type Block<P> = <T>(func: HTML) => {};
declare var h: HTML;
h.div(h);
//// [mappedTypeInferenceCircularity.js]
// Repro from #12511
h.div(h);
@@ -0,0 +1,26 @@
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
>K : Symbol(K, Decl(mappedTypeInferenceCircularity.ts, 2, 15))
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
type Block<P> = <T>(func: HTML) => {};
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
>P : Symbol(P, Decl(mappedTypeInferenceCircularity.ts, 3, 11))
>T : Symbol(T, Decl(mappedTypeInferenceCircularity.ts, 3, 17))
>func : Symbol(func, Decl(mappedTypeInferenceCircularity.ts, 3, 20))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
declare var h: HTML;
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
h.div(h);
>h.div : Symbol(div)
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
>div : Symbol(div)
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
@@ -0,0 +1,27 @@
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
>HTML : HTML
>K : K
>Block : Block<P>
>HTML : HTML
type Block<P> = <T>(func: HTML) => {};
>Block : Block<P>
>P : P
>T : T
>func : HTML
>HTML : HTML
declare var h: HTML;
>h : HTML
>HTML : HTML
h.div(h);
>h.div(h) : {}
>h.div : Block<HTML>
>h : HTML
>div : Block<HTML>
>h : HTML
@@ -0,0 +1,145 @@
//// [mappedTypeModifiers.ts]
type T = { a: number, b: string };
type TU = { a: number | undefined, b: string | undefined };
type TP = { a?: number, b?: string };
type TR = { readonly a: number, readonly b: string };
type TPR = { readonly a?: number, readonly b?: string };
// Validate they all have the same keys
var v00: "a" | "b";
var v00: keyof T;
var v00: keyof TU;
var v00: keyof TP;
var v00: keyof TR;
var v00: keyof TPR;
// Validate that non-isomorphic mapped types strip modifiers
var v01: T;
var v01: Pick<TR, keyof T>;
var v01: Pick<Readonly<T>, keyof T>;
// Validate that non-isomorphic mapped types strip modifiers
var v02: TU;
var v02: Pick<TP, keyof T>;
var v02: Pick<TPR, keyof T>;
var v02: Pick<Partial<T>, keyof T>;
var v02: Pick<Partial<Readonly<T>>, keyof T>;
// Validate that isomorphic mapped types preserve optional modifier
var v03: TP;
var v03: Partial<T>;
// Validate that isomorphic mapped types preserve readonly modifier
var v04: TR;
var v04: Readonly<T>;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05: TPR;
var v05: Partial<TR>;
var v05: Readonly<TP>;
var v05: Partial<Readonly<T>>;
var v05: Readonly<Partial<T>>;
type Boxified<T> = { [P in keyof T]: { x: T[P] } };
type B = { a: { x: number }, b: { x: string } };
type BU = { a: { x: number } | undefined, b: { x: string } | undefined };
type BP = { a?: { x: number }, b?: { x: string } };
type BR = { readonly a: { x: number }, readonly b: { x: string } };
type BPR = { readonly a?: { x: number }, readonly b?: { x: string } };
// Validate they all have the same keys
var b00: "a" | "b";
var b00: keyof B;
var b00: keyof BU;
var b00: keyof BP;
var b00: keyof BR;
var b00: keyof BPR;
// Validate that non-isomorphic mapped types strip modifiers
var b01: B;
var b01: Pick<BR, keyof B>;
var b01: Pick<Readonly<BR>, keyof B>;
// Validate that non-isomorphic mapped types strip modifiers
var b02: BU;
var b02: Pick<BP, keyof B>;
var b02: Pick<BPR, keyof B>;
var b02: Pick<Partial<B>, keyof B>;
var b02: Pick<Partial<Readonly<B>>, keyof B>;
// Validate that isomorphic mapped types preserve optional modifier
var b03: BP;
var b03: Partial<B>;
// Validate that isomorphic mapped types preserve readonly modifier
var b04: BR;
var b04: Readonly<B>;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05: BPR;
var b05: Partial<BR>;
var b05: Readonly<BP>;
var b05: Partial<Readonly<B>>;
var b05: Readonly<Partial<B>>;
//// [mappedTypeModifiers.js]
// Validate they all have the same keys
var v00;
var v00;
var v00;
var v00;
var v00;
var v00;
// Validate that non-isomorphic mapped types strip modifiers
var v01;
var v01;
var v01;
// Validate that non-isomorphic mapped types strip modifiers
var v02;
var v02;
var v02;
var v02;
var v02;
// Validate that isomorphic mapped types preserve optional modifier
var v03;
var v03;
// Validate that isomorphic mapped types preserve readonly modifier
var v04;
var v04;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05;
var v05;
var v05;
var v05;
var v05;
// Validate they all have the same keys
var b00;
var b00;
var b00;
var b00;
var b00;
var b00;
// Validate that non-isomorphic mapped types strip modifiers
var b01;
var b01;
var b01;
// Validate that non-isomorphic mapped types strip modifiers
var b02;
var b02;
var b02;
var b02;
var b02;
// Validate that isomorphic mapped types preserve optional modifier
var b03;
var b03;
// Validate that isomorphic mapped types preserve readonly modifier
var b04;
var b04;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05;
var b05;
var b05;
var b05;
var b05;
@@ -0,0 +1,313 @@
=== tests/cases/conformance/types/mapped/mappedTypeModifiers.ts ===
type T = { a: number, b: string };
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 1, 10))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 1, 21))
type TU = { a: number | undefined, b: string | undefined };
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 2, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 2, 34))
type TP = { a?: number, b?: string };
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 3, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 3, 23))
type TR = { readonly a: number, readonly b: string };
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 4, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 4, 31))
type TPR = { readonly a?: number, readonly b?: string };
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 5, 12))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 5, 33))
// Validate they all have the same keys
var v00: "a" | "b";
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
var v00: keyof T;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v00: keyof TU;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
var v00: keyof TP;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v00: keyof TR;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v00: keyof TPR;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
// Validate that non-isomorphic mapped types strip modifiers
var v01: T;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v01: Pick<TR, keyof T>;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v01: Pick<Readonly<T>, keyof T>;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that non-isomorphic mapped types strip modifiers
var v02: TU;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
var v02: Pick<TP, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<TPR, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<Partial<T>, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<Partial<Readonly<T>>, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve optional modifier
var v03: TP;
>v03 : Symbol(v03, Decl(mappedTypeModifiers.ts, 28, 3), Decl(mappedTypeModifiers.ts, 29, 3))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v03: Partial<T>;
>v03 : Symbol(v03, Decl(mappedTypeModifiers.ts, 28, 3), Decl(mappedTypeModifiers.ts, 29, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve readonly modifier
var v04: TR;
>v04 : Symbol(v04, Decl(mappedTypeModifiers.ts, 32, 3), Decl(mappedTypeModifiers.ts, 33, 3))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v04: Readonly<T>;
>v04 : Symbol(v04, Decl(mappedTypeModifiers.ts, 32, 3), Decl(mappedTypeModifiers.ts, 33, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05: TPR;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
var v05: Partial<TR>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v05: Readonly<TP>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v05: Partial<Readonly<T>>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v05: Readonly<Partial<T>>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
type Boxified<T> = { [P in keyof T]: { x: T[P] } };
>Boxified : Symbol(Boxified, Decl(mappedTypeModifiers.ts, 40, 30))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>P : Symbol(P, Decl(mappedTypeModifiers.ts, 42, 22))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 42, 38))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>P : Symbol(P, Decl(mappedTypeModifiers.ts, 42, 22))
type B = { a: { x: number }, b: { x: string } };
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 44, 10))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 44, 15))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 44, 28))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 44, 33))
type BU = { a: { x: number } | undefined, b: { x: string } | undefined };
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 45, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 45, 16))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 45, 41))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 45, 46))
type BP = { a?: { x: number }, b?: { x: string } };
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 46, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 46, 17))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 46, 30))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 46, 36))
type BR = { readonly a: { x: number }, readonly b: { x: string } };
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 47, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 47, 25))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 47, 38))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 47, 52))
type BPR = { readonly a?: { x: number }, readonly b?: { x: string } };
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 48, 12))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 48, 27))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 48, 40))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 48, 55))
// Validate they all have the same keys
var b00: "a" | "b";
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
var b00: keyof B;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b00: keyof BU;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
var b00: keyof BP;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b00: keyof BR;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b00: keyof BPR;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
// Validate that non-isomorphic mapped types strip modifiers
var b01: B;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b01: Pick<BR, keyof B>;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b01: Pick<Readonly<BR>, keyof B>;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that non-isomorphic mapped types strip modifiers
var b02: BU;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
var b02: Pick<BP, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<BPR, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<Partial<B>, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<Partial<Readonly<B>>, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve optional modifier
var b03: BP;
>b03 : Symbol(b03, Decl(mappedTypeModifiers.ts, 71, 3), Decl(mappedTypeModifiers.ts, 72, 3))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b03: Partial<B>;
>b03 : Symbol(b03, Decl(mappedTypeModifiers.ts, 71, 3), Decl(mappedTypeModifiers.ts, 72, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve readonly modifier
var b04: BR;
>b04 : Symbol(b04, Decl(mappedTypeModifiers.ts, 75, 3), Decl(mappedTypeModifiers.ts, 76, 3))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b04: Readonly<B>;
>b04 : Symbol(b04, Decl(mappedTypeModifiers.ts, 75, 3), Decl(mappedTypeModifiers.ts, 76, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05: BPR;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
var b05: Partial<BR>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b05: Readonly<BP>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b05: Partial<Readonly<B>>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b05: Readonly<Partial<B>>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))

Some files were not shown because too many files have changed in this diff Show More