mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into genericRest
# Conflicts: # tests/baselines/reference/objectRest.errors.txt # tests/baselines/reference/objectRest.types
This commit is contained in:
+35
-57
@@ -4628,6 +4628,10 @@ namespace ts {
|
||||
if (isTypeAny(parentType)) {
|
||||
return parentType;
|
||||
}
|
||||
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
|
||||
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
|
||||
parentType = getNonNullableType(parentType);
|
||||
}
|
||||
|
||||
let type: Type | undefined;
|
||||
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
@@ -4647,53 +4651,13 @@ namespace ts {
|
||||
else {
|
||||
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
|
||||
const name = declaration.propertyName || <Identifier>declaration.name;
|
||||
const isLate = isLateBindableName(name);
|
||||
const isWellKnown = isComputedPropertyName(name) && isWellKnownSymbolSyntactically(name.expression);
|
||||
if (!isLate && !isWellKnown && isComputedNonLiteralName(name)) {
|
||||
const exprType = checkExpression((name as ComputedPropertyName).expression);
|
||||
if (isTypeAssignableToKind(exprType, TypeFlags.ESSymbolLike)) {
|
||||
if (noImplicitAny) {
|
||||
error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(exprType), typeToString(parentType));
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
const indexerType = isTypeAssignableToKind(exprType, TypeFlags.NumberLike) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String);
|
||||
if (!indexerType && noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
|
||||
if (getIndexTypeOfType(parentType, IndexKind.Number)) {
|
||||
error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
|
||||
}
|
||||
else {
|
||||
error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(parentType));
|
||||
}
|
||||
}
|
||||
return indexerType || anyType;
|
||||
}
|
||||
|
||||
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
|
||||
// or otherwise the type of the string index signature.
|
||||
const nameType = isLate ? checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType : undefined;
|
||||
const text = isLate ? getLateBoundNameFromType(nameType!) :
|
||||
isWellKnown ? getPropertyNameForKnownSymbolName(idText(((name as ComputedPropertyName).expression as PropertyAccessExpression).name)) :
|
||||
getTextOfPropertyName(name);
|
||||
|
||||
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
|
||||
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
|
||||
parentType = getNonNullableType(parentType);
|
||||
}
|
||||
if (isLate && nameType && !getPropertyOfType(parentType, text) && isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike)) {
|
||||
if (noImplicitAny) {
|
||||
error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(nameType), typeToString(parentType));
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
const declaredType = getConstraintForLocation(getTypeOfPropertyOfType(parentType, text), declaration.name);
|
||||
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(parentType, IndexKind.String);
|
||||
if (!type) {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
|
||||
return errorType;
|
||||
}
|
||||
const exprType = isComputedPropertyName(name)
|
||||
? checkComputedPropertyName(name)
|
||||
: isIdentifier(name)
|
||||
? getLiteralType(unescapeLeadingUnderscores(name.escapedText))
|
||||
: checkExpression(name);
|
||||
const declaredType = checkIndexedAccessIndexType(getIndexedAccessType(getApparentType(parentType), exprType, name), name);
|
||||
type = getFlowTypeOfReference(declaration, getConstraintForLocation(declaredType, declaration.name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -9360,12 +9324,16 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | undefined, cacheSymbol: boolean, missingType: Type) {
|
||||
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | undefined, cacheSymbol: boolean, missingType: Type) {
|
||||
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
|
||||
const propName = isTypeUsableAsLateBoundName(indexType) ? getLateBoundNameFromType(indexType) :
|
||||
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
|
||||
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
|
||||
undefined;
|
||||
const propName = isTypeUsableAsLateBoundName(indexType)
|
||||
? getLateBoundNameFromType(indexType)
|
||||
: accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false)
|
||||
? getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name))
|
||||
: accessNode && isPropertyName(accessNode)
|
||||
// late bound names are handled in the first branch, so here we only need to handle normal names
|
||||
? getPropertyNameForPropertyNameNode(accessNode)
|
||||
: undefined;
|
||||
if (propName !== undefined) {
|
||||
const prop = getPropertyOfType(objectType, propName);
|
||||
if (prop) {
|
||||
@@ -9386,7 +9354,7 @@ namespace ts {
|
||||
}
|
||||
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
|
||||
if (accessNode && everyType(objectType, t => !(<TupleTypeReference>t).target.hasRestElement)) {
|
||||
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType;
|
||||
const indexNode = getIndexNodeForAccessExpression(accessNode);
|
||||
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
|
||||
}
|
||||
return mapType(objectType, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
|
||||
@@ -9401,7 +9369,7 @@ namespace ts {
|
||||
undefined;
|
||||
if (indexInfo) {
|
||||
if (accessNode && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) {
|
||||
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType;
|
||||
const indexNode = getIndexNodeForAccessExpression(accessNode);
|
||||
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
|
||||
}
|
||||
else if (accessExpression && indexInfo.isReadonly && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
|
||||
@@ -9442,7 +9410,7 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
if (accessNode) {
|
||||
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType;
|
||||
const indexNode = getIndexNodeForAccessExpression(accessNode);
|
||||
if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
|
||||
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, "" + (<LiteralType>indexType).value, typeToString(objectType));
|
||||
}
|
||||
@@ -9459,6 +9427,16 @@ namespace ts {
|
||||
return missingType;
|
||||
}
|
||||
|
||||
function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName) {
|
||||
return accessNode.kind === SyntaxKind.ElementAccessExpression
|
||||
? accessNode.argumentExpression
|
||||
: accessNode.kind === SyntaxKind.IndexedAccessType
|
||||
? accessNode.indexType
|
||||
: accessNode.kind === SyntaxKind.ComputedPropertyName
|
||||
? accessNode.expression
|
||||
: accessNode;
|
||||
}
|
||||
|
||||
function isGenericObjectType(type: Type): boolean {
|
||||
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.GenericMappedType);
|
||||
}
|
||||
@@ -9522,7 +9500,7 @@ namespace ts {
|
||||
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
|
||||
}
|
||||
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode, missingType = accessNode ? errorType : unknownType): Type {
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName, missingType = accessNode ? errorType : unknownType): Type {
|
||||
if (objectType === wildcardType || indexType === wildcardType) {
|
||||
return wildcardType;
|
||||
}
|
||||
@@ -23208,7 +23186,7 @@ namespace ts {
|
||||
forEach(node.types, checkSourceElement);
|
||||
}
|
||||
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode) {
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: Node) {
|
||||
if (!(type.flags & TypeFlags.IndexedAccess)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,13 @@ namespace ts {
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
|
||||
},
|
||||
{
|
||||
name: "showConfig",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Command_line_Options,
|
||||
isCommandLineOnly: true,
|
||||
description: Diagnostics.Print_the_final_configuration_instead_of_building
|
||||
},
|
||||
|
||||
// Basic
|
||||
{
|
||||
@@ -1653,6 +1660,137 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an uncommented, complete tsconfig for use with "--showConfig"
|
||||
* @param configParseResult options to be generated into tsconfig.json
|
||||
* @param configFileName name of the parsed config file - output paths will be generated relative to this
|
||||
* @param host provides current directory and case sensitivity services
|
||||
*/
|
||||
/** @internal */
|
||||
export function convertToTSConfig(configParseResult: ParsedCommandLine, configFileName: string, host: { getCurrentDirectory(): string, useCaseSensitiveFileNames: boolean }): object {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
const files = map(
|
||||
filter(
|
||||
configParseResult.fileNames,
|
||||
!configParseResult.configFileSpecs ? _ => false : matchesSpecs(
|
||||
configFileName,
|
||||
configParseResult.configFileSpecs.validatedIncludeSpecs,
|
||||
configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
)
|
||||
),
|
||||
f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), f, getCanonicalFileName)
|
||||
);
|
||||
const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}),
|
||||
showConfig: undefined,
|
||||
configFile: undefined,
|
||||
configFilePath: undefined,
|
||||
help: undefined,
|
||||
init: undefined,
|
||||
listFiles: undefined,
|
||||
listEmittedFiles: undefined,
|
||||
project: undefined,
|
||||
},
|
||||
references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath, originalPath: undefined })),
|
||||
files: length(files) ? files : undefined,
|
||||
...(configParseResult.configFileSpecs ? {
|
||||
include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
|
||||
exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
} : {}),
|
||||
compilerOnSave: !!configParseResult.compileOnSave ? true : undefined
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
function filterSameAsDefaultInclude(specs: ReadonlyArray<string> | undefined) {
|
||||
if (!length(specs)) return undefined;
|
||||
if (length(specs) !== 1) return specs;
|
||||
if (specs![0] === "**/*") return undefined;
|
||||
return specs;
|
||||
}
|
||||
|
||||
function matchesSpecs(path: string, includeSpecs: ReadonlyArray<string> | undefined, excludeSpecs: ReadonlyArray<string> | undefined): (path: string) => boolean {
|
||||
if (!includeSpecs) return _ => false;
|
||||
const patterns = getFileMatcherPatterns(path, excludeSpecs, includeSpecs, sys.useCaseSensitiveFileNames, sys.getCurrentDirectory());
|
||||
const excludeRe = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, sys.useCaseSensitiveFileNames);
|
||||
const includeRe = patterns.includeFilePattern && getRegexFromPattern(patterns.includeFilePattern, sys.useCaseSensitiveFileNames);
|
||||
if (includeRe) {
|
||||
if (excludeRe) {
|
||||
return path => includeRe.test(path) && !excludeRe.test(path);
|
||||
}
|
||||
return path => includeRe.test(path);
|
||||
}
|
||||
if (excludeRe) {
|
||||
return path => !excludeRe.test(path);
|
||||
}
|
||||
return _ => false;
|
||||
}
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean }): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
if (pathOptions && optionDefinition.isFilePath) {
|
||||
result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value as string, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!));
|
||||
}
|
||||
else {
|
||||
result.set(name, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tsconfig configuration when running command line "--init"
|
||||
* @param options commandlineOptions to be generated into tsconfig.json
|
||||
@@ -1664,63 +1802,6 @@ namespace ts {
|
||||
const compilerOptionsMap = serializeCompilerOptions(compilerOptions);
|
||||
return writeConfigurations();
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
result.set(name, value);
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultValueForOption(option: CommandLineOption) {
|
||||
switch (option.type) {
|
||||
case "number":
|
||||
|
||||
@@ -1007,6 +1007,10 @@
|
||||
"category": "Error",
|
||||
"code": 1349
|
||||
},
|
||||
"Print the final configuration instead of building.": {
|
||||
"category": "Message",
|
||||
"code": 1350
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace ts.sourcemaps {
|
||||
fileExists(path: string): boolean;
|
||||
getCanonicalFileName(path: string): string;
|
||||
log(text: string): void;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
}
|
||||
|
||||
export function decode(host: SourceMapDecodeHost, mapPath: string, map: SourceMapData, program?: Program, fallbackCache = createSourceFileLikeCache(host)): SourceMapper {
|
||||
@@ -79,7 +80,7 @@ namespace ts.sourcemaps {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot) !== 0) {
|
||||
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) !== 0) {
|
||||
return loc;
|
||||
}
|
||||
return { fileName: toPath(map.file!, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos
|
||||
@@ -129,7 +130,7 @@ namespace ts.sourcemaps {
|
||||
}
|
||||
|
||||
function compareProcessedPositionSourcePositions(a: ProcessedSourceMapPosition, b: ProcessedSourceMapPosition) {
|
||||
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot) ||
|
||||
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) ||
|
||||
compareValues(a.sourcePosition, b.sourcePosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -4556,6 +4556,7 @@ namespace ts {
|
||||
/*@internal*/ version?: boolean;
|
||||
/*@internal*/ watch?: boolean;
|
||||
esModuleInterop?: boolean;
|
||||
/* @internal */ showConfig?: boolean;
|
||||
|
||||
[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
|
||||
}
|
||||
|
||||
@@ -2921,7 +2921,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getBinaryOperatorPrecedence(kind: SyntaxKind): number {
|
||||
switch (kind) {
|
||||
case SyntaxKind.BarBarToken:
|
||||
@@ -6834,7 +6833,6 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/** @internal */
|
||||
export function isNamedImportsOrExports(node: Node): node is NamedImportsOrExports {
|
||||
return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
|
||||
}
|
||||
@@ -6898,7 +6896,6 @@ namespace ts {
|
||||
getSourceMapSourceConstructor: () => <any>SourceMapSource,
|
||||
};
|
||||
|
||||
/* @internal */
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
}
|
||||
@@ -6909,7 +6906,6 @@ namespace ts {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation {
|
||||
Debug.assertGreaterThanOrEqual(start, 0);
|
||||
@@ -6938,7 +6934,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -6949,7 +6944,6 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -6970,7 +6964,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
@@ -6983,7 +6976,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -7015,14 +7007,12 @@ namespace ts {
|
||||
return diagnostic.file ? diagnostic.file.path : undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
|
||||
compareRelatedInformation(d1, d2) ||
|
||||
Comparison.EqualTo;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnosticsSkipRelatedInformation(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
|
||||
compareValues(d1.start, d2.start) ||
|
||||
@@ -7360,7 +7350,6 @@ namespace ts {
|
||||
return rootLength > 0 && rootLength === path.length;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string {
|
||||
return !isRootedDiskPath(absoluteOrRelativePath)
|
||||
? absoluteOrRelativePath
|
||||
|
||||
@@ -2401,6 +2401,7 @@ namespace ts.server.protocol {
|
||||
*/
|
||||
export interface DiagnosticEvent extends Event {
|
||||
body?: DiagnosticEventBody;
|
||||
event: DiagnosticEventKind;
|
||||
}
|
||||
|
||||
export interface ConfigFileDiagnosticEventBody {
|
||||
@@ -2520,6 +2521,10 @@ namespace ts.server.protocol {
|
||||
maxFileSize: number;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export type AnyEvent = RequestCompletedEvent | DiagnosticEvent | ConfigFileDiagnosticEvent | ProjectLanguageServiceStateEvent | TelemetryEvent |
|
||||
ProjectsUpdatedInBackgroundEvent | ProjectLoadingStartEvent | ProjectLoadingFinishEvent | SurveyReadyEvent | LargeFileReferencedEvent;
|
||||
|
||||
/**
|
||||
* Arguments for reload request.
|
||||
*/
|
||||
|
||||
@@ -576,7 +576,7 @@ namespace ts.server {
|
||||
break;
|
||||
case ProjectLoadingFinishEvent:
|
||||
const { project: finishProject } = event.data;
|
||||
this.event<protocol.ProjectLoadingFinishEventBody>({ projectName: finishProject.getProjectName() }, ProjectLoadingStartEvent);
|
||||
this.event<protocol.ProjectLoadingFinishEventBody>({ projectName: finishProject.getProjectName() }, ProjectLoadingFinishEvent);
|
||||
break;
|
||||
case LargeFileReferencedEvent:
|
||||
const { file, fileSize, maxFileSize } = event.data;
|
||||
|
||||
@@ -1139,7 +1139,7 @@ namespace ts {
|
||||
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
const sourceMapper = getSourceMapper(getCanonicalFileName, currentDirectory, log, host, () => program);
|
||||
const sourceMapper = getSourceMapper(useCaseSensitiveFileNames, currentDirectory, log, host, () => program);
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
const sourceFile = program.getSourceFile(fileName);
|
||||
|
||||
@@ -13,12 +13,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getSourceMapper(
|
||||
getCanonicalFileName: GetCanonicalFileName,
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
currentDirectory: string,
|
||||
log: (message: string) => void,
|
||||
host: LanguageServiceHost,
|
||||
getProgram: () => Program,
|
||||
): SourceMapper {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
let sourcemappedFileCache: SourceFileLikeCache;
|
||||
return { tryGetOriginalLocation, tryGetGeneratedLocation, toLineColumnOffset, clearCache };
|
||||
|
||||
@@ -56,6 +57,7 @@ namespace ts {
|
||||
return file.sourceMapper = sourcemaps.decode({
|
||||
readFile: s => host.readFile!(s), // TODO: GH#18217
|
||||
fileExists: s => host.fileExists!(s), // TODO: GH#18217
|
||||
useCaseSensitiveFileNames,
|
||||
getCanonicalFileName,
|
||||
log,
|
||||
}, mapFileName, maps, getProgram(), sourcemappedFileCache);
|
||||
@@ -105,7 +107,11 @@ namespace ts {
|
||||
|
||||
function tryGetGeneratedLocation(info: sourcemaps.SourceMappableLocation): sourcemaps.SourceMappableLocation | undefined {
|
||||
const program = getProgram();
|
||||
const declarationPath = getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
|
||||
const options = program.getCompilerOptions();
|
||||
const outPath = options.outFile || options.out;
|
||||
const declarationPath = outPath ?
|
||||
removeFileExtension(outPath) + Extension.Dts :
|
||||
getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
|
||||
if (declarationPath === undefined) return undefined;
|
||||
const declarationFile = getFile(declarationPath);
|
||||
if (!declarationFile) return undefined;
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"unittests/reuseProgramStructure.ts",
|
||||
"unittests/session.ts",
|
||||
"unittests/semver.ts",
|
||||
"unittests/showConfig.ts",
|
||||
"unittests/symbolWalker.ts",
|
||||
"unittests/telemetry.ts",
|
||||
"unittests/textChanges.ts",
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace ts {
|
||||
describe("showTSConfig", () => {
|
||||
function showTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
|
||||
describe(name, () => {
|
||||
const commandLine = parseCommandLine(commandLinesArgs);
|
||||
const initResult = convertToTSConfig(commandLine, `/${name}/tsconfig.json`, { getCurrentDirectory() { return `/${name}`; }, useCaseSensitiveFileNames: true });
|
||||
const outputFileName = `showConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
Harness.Baseline.runBaseline(outputFileName, JSON.stringify(initResult, null, 4) + "\n");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showTSConfigCorrectly("Default initialized TSConfig", ["--showConfig"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with files options", ["--showConfig", "file0.st", "file1.ts", "file2.ts"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with boolean value compiler options", ["--showConfig", "--noUnusedLocals"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with enum value compiler options", ["--showConfig", "--target", "es5", "--jsx", "react"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with list compiler options", ["--showConfig", "--types", "jquery,mocha"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with list compiler options with enum value", ["--showConfig", "--lib", "es5,es2015.core"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with incorrect compiler option", ["--showConfig", "--someNonExistOption"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with incorrect compiler option value", ["--showConfig", "--lib", "nonExistLib,es5,es2015.promise"]);
|
||||
|
||||
showTSConfigCorrectly("Show TSConfig with advanced options", ["--showConfig", "--declaration", "--declarationDir", "lib", "--skipLibCheck", "--noErrorTruncation"]);
|
||||
});
|
||||
}
|
||||
@@ -330,12 +330,12 @@ namespace ts.projectSystem {
|
||||
return new TestSession({ ...sessionOptions, ...opts });
|
||||
}
|
||||
|
||||
function createSessionWithEventTracking<T extends server.ProjectServiceEvent, U extends server.ProjectServiceEvent = T>(host: server.ServerHost, eventName: T["eventName"], eventName2?: U["eventName"]) {
|
||||
const events: (T | U)[] = [];
|
||||
function createSessionWithEventTracking<T extends server.ProjectServiceEvent>(host: server.ServerHost, eventName: T["eventName"], ...eventNames: T["eventName"][]) {
|
||||
const events: T[] = [];
|
||||
const session = createSession(host, {
|
||||
eventHandler: e => {
|
||||
if (e.eventName === eventName || (eventName2 && e.eventName === eventName2)) {
|
||||
events.push(e as T | U);
|
||||
if (e.eventName === eventName || eventNames.some(eventName => e.eventName === eventName)) {
|
||||
events.push(e as T);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -343,6 +343,31 @@ namespace ts.projectSystem {
|
||||
return { session, events };
|
||||
}
|
||||
|
||||
function createSessionWithDefaultEventHandler<T extends protocol.AnyEvent>(host: TestServerHost, eventNames: T["event"] | T["event"][], opts: Partial<server.SessionOptions> = {}) {
|
||||
const session = createSession(host, { canUseEvents: true, ...opts });
|
||||
|
||||
return {
|
||||
session,
|
||||
getEvents,
|
||||
clearEvents
|
||||
};
|
||||
|
||||
function getEvents() {
|
||||
const outputEventRegex = /Content\-Length: [\d]+\r\n\r\n/;
|
||||
return mapDefined(host.getOutput(), s => {
|
||||
const e = convertToObject(
|
||||
parseJsonText("json.json", s.replace(outputEventRegex, "")),
|
||||
[]
|
||||
);
|
||||
return (isArray(eventNames) ? eventNames.some(eventName => e.event === eventName) : e.event === eventNames) ? e as T : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
function clearEvents() {
|
||||
session.clearMessages();
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateProjectServiceParameters {
|
||||
cancellationToken?: HostCancellationToken;
|
||||
logger?: server.Logger;
|
||||
@@ -8062,15 +8087,7 @@ namespace ts.projectSystem {
|
||||
verifyProjectsUpdatedInBackgroundEvent(createSessionWithProjectChangedEventHandler);
|
||||
|
||||
function createSessionWithProjectChangedEventHandler(host: TestServerHost): ProjectsUpdatedInBackgroundEventVerifier {
|
||||
const projectChangedEvents: server.ProjectsUpdatedInBackgroundEvent[] = [];
|
||||
const session = createSession(host, {
|
||||
eventHandler: e => {
|
||||
if (e.eventName === server.ProjectsUpdatedInBackgroundEvent) {
|
||||
projectChangedEvents.push(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const { session, events: projectChangedEvents } = createSessionWithEventTracking<server.ProjectsUpdatedInBackgroundEvent>(host, server.ProjectsUpdatedInBackgroundEvent);
|
||||
return {
|
||||
session,
|
||||
verifyProjectsUpdatedInBackgroundEventHandler,
|
||||
@@ -8110,7 +8127,7 @@ namespace ts.projectSystem {
|
||||
|
||||
|
||||
function createSessionThatUsesEvents(host: TestServerHost, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier {
|
||||
const session = createSession(host, { canUseEvents: true, noGetErrOnBackgroundUpdate });
|
||||
const { session, getEvents, clearEvents } = createSessionWithDefaultEventHandler<protocol.ProjectsUpdatedInBackgroundEvent>(host, server.ProjectsUpdatedInBackgroundEvent, { noGetErrOnBackgroundUpdate });
|
||||
|
||||
return {
|
||||
session,
|
||||
@@ -8124,16 +8141,7 @@ namespace ts.projectSystem {
|
||||
openFiles: e.data.openFiles
|
||||
};
|
||||
});
|
||||
const outputEventRegex = /Content\-Length: [\d]+\r\n\r\n/;
|
||||
const events: protocol.ProjectsUpdatedInBackgroundEvent[] = filter(
|
||||
map(
|
||||
host.getOutput(), s => convertToObject(
|
||||
parseJsonText("json.json", s.replace(outputEventRegex, "")),
|
||||
[]
|
||||
)
|
||||
),
|
||||
e => e.event === server.ProjectsUpdatedInBackgroundEvent
|
||||
);
|
||||
const events = getEvents();
|
||||
assert.equal(events.length, expectedEvents.length, `Incorrect number of events Actual: ${map(events, e => e.body)} Expected: ${expectedEvents}`);
|
||||
forEach(events, (actualEvent, i) => {
|
||||
const expectedEvent = expectedEvents[i];
|
||||
@@ -8141,7 +8149,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
// Verified the events, reset them
|
||||
session.clearMessages();
|
||||
clearEvents();
|
||||
|
||||
if (events.length) {
|
||||
host.checkTimeoutQueueLength(noGetErrOnBackgroundUpdate ? 0 : 1); // Error checking queued only if not noGetErrOnBackgroundUpdate
|
||||
@@ -9457,141 +9465,180 @@ export const x = 10;`
|
||||
const configBPath = `${projectRoot}/b/tsconfig.json`;
|
||||
const files = [libFile, aTs, configA];
|
||||
|
||||
function createSessionWithEventHandler(files: ReadonlyArray<File>) {
|
||||
const host = createServerHost(files);
|
||||
function verifyProjectLoadingStartAndFinish(createSession: (host: TestServerHost) => {
|
||||
session: TestSession;
|
||||
getNumberOfEvents: () => number;
|
||||
clearEvents: () => void;
|
||||
verifyProjectLoadEvents: (expected: [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]) => void;
|
||||
}) {
|
||||
function createSessionToVerifyEvent(files: ReadonlyArray<File>) {
|
||||
const host = createServerHost(files);
|
||||
const originalReadFile = host.readFile;
|
||||
const { session, getNumberOfEvents, clearEvents, verifyProjectLoadEvents } = createSession(host);
|
||||
host.readFile = file => {
|
||||
if (file === configA.path || file === configBPath) {
|
||||
assert.equal(getNumberOfEvents(), 1, "Event for loading is sent before reading config file");
|
||||
}
|
||||
return originalReadFile.call(host, file);
|
||||
};
|
||||
const service = session.getProjectService();
|
||||
return { host, session, verifyEvent, verifyEventWithOpenTs, service, getNumberOfEvents };
|
||||
|
||||
const originalReadFile = host.readFile;
|
||||
host.readFile = file => {
|
||||
if (file === configA.path || file === configBPath) {
|
||||
assert.equal(events.length, 1, "Event for loading is sent before reading config file");
|
||||
function verifyEvent(project: server.Project, reason: string) {
|
||||
verifyProjectLoadEvents([
|
||||
{ eventName: server.ProjectLoadingStartEvent, data: { project, reason } },
|
||||
{ eventName: server.ProjectLoadingFinishEvent, data: { project } }
|
||||
]);
|
||||
clearEvents();
|
||||
}
|
||||
return originalReadFile.call(host, file);
|
||||
};
|
||||
const { session, events } = createSessionWithEventTracking<server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent>(host, server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent);
|
||||
const service = session.getProjectService();
|
||||
return { host, session, verifyEvent, verifyEventWithOpenTs, service, events };
|
||||
|
||||
function verifyEvent(project: server.Project, reason: string) {
|
||||
assert.deepEqual(events, [
|
||||
{ eventName: server.ProjectLoadingStartEvent, data: { project, reason } },
|
||||
{ eventName: server.ProjectLoadingFinishEvent, data: { project } }
|
||||
]);
|
||||
events.length = 0;
|
||||
function verifyEventWithOpenTs(file: File, configPath: string, configuredProjects: number) {
|
||||
openFilesForSession([file], session);
|
||||
checkNumberOfProjects(service, { configuredProjects });
|
||||
const project = service.configuredProjects.get(configPath)!;
|
||||
assert.isDefined(project);
|
||||
verifyEvent(project, `Creating possible configured project for ${file.path} to open`);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyEventWithOpenTs(file: File, configPath: string, configuredProjects: number) {
|
||||
openFilesForSession([file], session);
|
||||
checkNumberOfProjects(service, { configuredProjects });
|
||||
const project = service.configuredProjects.get(configPath)!;
|
||||
assert.isDefined(project);
|
||||
verifyEvent(project, `Creating possible configured project for ${file.path} to open`);
|
||||
}
|
||||
}
|
||||
it("when project is created by open file", () => {
|
||||
const bTs: File = {
|
||||
path: bTsPath,
|
||||
content: "export class B {}"
|
||||
};
|
||||
const configB: File = {
|
||||
path: configBPath,
|
||||
content: "{}"
|
||||
};
|
||||
const { verifyEventWithOpenTs } = createSessionToVerifyEvent(files.concat(bTs, configB));
|
||||
verifyEventWithOpenTs(aTs, configA.path, 1);
|
||||
verifyEventWithOpenTs(bTs, configB.path, 2);
|
||||
});
|
||||
|
||||
it("when project is created by open file", () => {
|
||||
const bTs: File = {
|
||||
path: bTsPath,
|
||||
content: "export class B {}"
|
||||
};
|
||||
const configB: File = {
|
||||
path: configBPath,
|
||||
content: "{}"
|
||||
};
|
||||
const { verifyEventWithOpenTs } = createSessionWithEventHandler(files.concat(bTs, configB));
|
||||
verifyEventWithOpenTs(aTs, configA.path, 1);
|
||||
verifyEventWithOpenTs(bTs, configB.path, 2);
|
||||
});
|
||||
it("when change is detected in the config file", () => {
|
||||
const { host, verifyEvent, verifyEventWithOpenTs, service } = createSessionToVerifyEvent(files);
|
||||
verifyEventWithOpenTs(aTs, configA.path, 1);
|
||||
|
||||
it("when change is detected in the config file", () => {
|
||||
const { host, verifyEvent, verifyEventWithOpenTs, service } = createSessionWithEventHandler(files);
|
||||
verifyEventWithOpenTs(aTs, configA.path, 1);
|
||||
host.writeFile(configA.path, configA.content);
|
||||
host.checkTimeoutQueueLengthAndRun(2);
|
||||
const project = service.configuredProjects.get(configA.path)!;
|
||||
verifyEvent(project, `Change in config file detected`);
|
||||
});
|
||||
|
||||
host.writeFile(configA.path, configA.content);
|
||||
host.checkTimeoutQueueLengthAndRun(2);
|
||||
const project = service.configuredProjects.get(configA.path)!;
|
||||
verifyEvent(project, `Change in config file detected`);
|
||||
});
|
||||
|
||||
it("when opening original location project", () => {
|
||||
const aDTs: File = {
|
||||
path: `${projectRoot}/a/a.d.ts`,
|
||||
content: `export declare class A {
|
||||
it("when opening original location project", () => {
|
||||
const aDTs: File = {
|
||||
path: `${projectRoot}/a/a.d.ts`,
|
||||
content: `export declare class A {
|
||||
}
|
||||
//# sourceMappingURL=a.d.ts.map
|
||||
`
|
||||
};
|
||||
const aDTsMap: File = {
|
||||
path: `${projectRoot}/a/a.d.ts.map`,
|
||||
content: `{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["./a.ts"],"names":[],"mappings":"AAAA,qBAAa,CAAC;CAAI"}`
|
||||
};
|
||||
const bTs: File = {
|
||||
path: bTsPath,
|
||||
content: `import {A} from "../a/a"; new A();`
|
||||
};
|
||||
const configB: File = {
|
||||
path: configBPath,
|
||||
content: JSON.stringify({
|
||||
references: [{ path: "../a" }]
|
||||
})
|
||||
};
|
||||
};
|
||||
const aDTsMap: File = {
|
||||
path: `${projectRoot}/a/a.d.ts.map`,
|
||||
content: `{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["./a.ts"],"names":[],"mappings":"AAAA,qBAAa,CAAC;CAAI"}`
|
||||
};
|
||||
const bTs: File = {
|
||||
path: bTsPath,
|
||||
content: `import {A} from "../a/a"; new A();`
|
||||
};
|
||||
const configB: File = {
|
||||
path: configBPath,
|
||||
content: JSON.stringify({
|
||||
references: [{ path: "../a" }]
|
||||
})
|
||||
};
|
||||
|
||||
const { service, session, verifyEventWithOpenTs, verifyEvent } = createSessionWithEventHandler(files.concat(aDTs, aDTsMap, bTs, configB));
|
||||
verifyEventWithOpenTs(bTs, configB.path, 1);
|
||||
const { service, session, verifyEventWithOpenTs, verifyEvent } = createSessionToVerifyEvent(files.concat(aDTs, aDTsMap, bTs, configB));
|
||||
verifyEventWithOpenTs(bTs, configB.path, 1);
|
||||
|
||||
session.executeCommandSeq<protocol.ReferencesRequest>({
|
||||
command: protocol.CommandTypes.References,
|
||||
arguments: {
|
||||
file: bTs.path,
|
||||
...protocolLocationFromSubstring(bTs.content, "A()")
|
||||
}
|
||||
session.executeCommandSeq<protocol.ReferencesRequest>({
|
||||
command: protocol.CommandTypes.References,
|
||||
arguments: {
|
||||
file: bTs.path,
|
||||
...protocolLocationFromSubstring(bTs.content, "A()")
|
||||
}
|
||||
});
|
||||
|
||||
checkNumberOfProjects(service, { configuredProjects: 2 });
|
||||
const project = service.configuredProjects.get(configA.path)!;
|
||||
assert.isDefined(project);
|
||||
verifyEvent(project, `Creating project for original file: ${aTs.path} for location: ${aDTs.path}`);
|
||||
});
|
||||
|
||||
checkNumberOfProjects(service, { configuredProjects: 2 });
|
||||
const project = service.configuredProjects.get(configA.path)!;
|
||||
assert.isDefined(project);
|
||||
verifyEvent(project, `Creating project for original file: ${aTs.path} for location: ${aDTs.path}`);
|
||||
describe("with external projects and config files ", () => {
|
||||
const projectFileName = `${projectRoot}/a/project.csproj`;
|
||||
|
||||
function createSession(lazyConfiguredProjectsFromExternalProject: boolean) {
|
||||
const { session, service, verifyEvent: verifyEventWorker, getNumberOfEvents } = createSessionToVerifyEvent(files);
|
||||
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } });
|
||||
service.openExternalProject(<protocol.ExternalProject>{
|
||||
projectFileName,
|
||||
rootFiles: toExternalFiles([aTs.path, configA.path]),
|
||||
options: {}
|
||||
});
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
return { session, service, verifyEvent, getNumberOfEvents };
|
||||
|
||||
function verifyEvent() {
|
||||
const projectA = service.configuredProjects.get(configA.path)!;
|
||||
assert.isDefined(projectA);
|
||||
verifyEventWorker(projectA, `Creating configured project in external project: ${projectFileName}`);
|
||||
}
|
||||
}
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is false", () => {
|
||||
const { verifyEvent } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ false);
|
||||
verifyEvent();
|
||||
});
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is true and file is opened", () => {
|
||||
const { verifyEvent, getNumberOfEvents, session } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
|
||||
assert.equal(getNumberOfEvents(), 0);
|
||||
|
||||
openFilesForSession([aTs], session);
|
||||
verifyEvent();
|
||||
});
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is disabled", () => {
|
||||
const { verifyEvent, getNumberOfEvents, service } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
|
||||
assert.equal(getNumberOfEvents(), 0);
|
||||
|
||||
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: false } });
|
||||
verifyEvent();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe("when using event handler", () => {
|
||||
verifyProjectLoadingStartAndFinish(host => {
|
||||
const { session, events } = createSessionWithEventTracking<server.ProjectLoadingStartEvent | server.ProjectLoadingFinishEvent>(host, server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent);
|
||||
return {
|
||||
session,
|
||||
getNumberOfEvents: () => events.length,
|
||||
clearEvents: () => events.length = 0,
|
||||
verifyProjectLoadEvents: expected => assert.deepEqual(events, expected)
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
describe("with external projects and config files ", () => {
|
||||
const projectFileName = `${projectRoot}/a/project.csproj`;
|
||||
describe("when using default event handler", () => {
|
||||
verifyProjectLoadingStartAndFinish(host => {
|
||||
const { session, getEvents, clearEvents } = createSessionWithDefaultEventHandler<protocol.ProjectLoadingStartEvent | protocol.ProjectLoadingFinishEvent>(host, [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]);
|
||||
return {
|
||||
session,
|
||||
getNumberOfEvents: () => getEvents().length,
|
||||
clearEvents,
|
||||
verifyProjectLoadEvents
|
||||
};
|
||||
|
||||
function createSession(lazyConfiguredProjectsFromExternalProject: boolean) {
|
||||
const { session, service, verifyEvent: verifyEventWorker, events } = createSessionWithEventHandler(files);
|
||||
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } });
|
||||
service.openExternalProject(<protocol.ExternalProject>{
|
||||
projectFileName,
|
||||
rootFiles: toExternalFiles([aTs.path, configA.path]),
|
||||
options: {}
|
||||
});
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
return { session, service, verifyEvent, events };
|
||||
|
||||
function verifyEvent() {
|
||||
const projectA = service.configuredProjects.get(configA.path)!;
|
||||
assert.isDefined(projectA);
|
||||
verifyEventWorker(projectA, `Creating configured project in external project: ${projectFileName}`);
|
||||
function verifyProjectLoadEvents(expected: [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]) {
|
||||
const actual = getEvents().map(e => ({ eventName: e.event, data: e.body }));
|
||||
const mappedExpected = expected.map(e => {
|
||||
const { project, ...rest } = e.data;
|
||||
return { eventName: e.eventName, data: { projectName: project.getProjectName(), ...rest } };
|
||||
});
|
||||
assert.deepEqual(actual, mappedExpected);
|
||||
}
|
||||
}
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is false", () => {
|
||||
const { verifyEvent } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ false);
|
||||
verifyEvent();
|
||||
});
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is true and file is opened", () => {
|
||||
const { verifyEvent, events, session } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
|
||||
assert.equal(events.length, 0);
|
||||
|
||||
openFilesForSession([aTs], session);
|
||||
verifyEvent();
|
||||
});
|
||||
|
||||
it("when lazyConfiguredProjectsFromExternalProject is disabled", () => {
|
||||
const { verifyEvent, events, service } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
|
||||
assert.equal(events.length, 0);
|
||||
|
||||
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: false } });
|
||||
verifyEvent();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10481,13 +10528,15 @@ declare class TestLib {
|
||||
TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"),
|
||||
];
|
||||
}
|
||||
it("does not error on container only project", () => {
|
||||
const project = "container";
|
||||
const containerLib = getProjectFiles("container/lib");
|
||||
const containerExec = getProjectFiles("container/exec");
|
||||
const containerCompositeExec = getProjectFiles("container/compositeExec");
|
||||
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
|
||||
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
|
||||
|
||||
const project = "container";
|
||||
const containerLib = getProjectFiles("container/lib");
|
||||
const containerExec = getProjectFiles("container/exec");
|
||||
const containerCompositeExec = getProjectFiles("container/compositeExec");
|
||||
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
|
||||
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
|
||||
|
||||
function createHost() {
|
||||
const host = createServerHost(files);
|
||||
|
||||
// ts build should succeed
|
||||
@@ -10495,6 +10544,12 @@ declare class TestLib {
|
||||
solutionBuilder.buildAllProjects();
|
||||
assert.equal(host.getOutput().length, 0);
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
it("does not error on container only project", () => {
|
||||
const host = createHost();
|
||||
|
||||
// Open external project for the folder
|
||||
const session = createSession(host);
|
||||
const service = session.getProjectService();
|
||||
@@ -10521,6 +10576,30 @@ declare class TestLib {
|
||||
assert.deepEqual(semanticDiagnostics, []);
|
||||
});
|
||||
});
|
||||
|
||||
it("can successfully find references with --out options", () => {
|
||||
const host = createHost();
|
||||
const session = createSession(host);
|
||||
openFilesForSession([containerCompositeExec[1]], session);
|
||||
const service = session.getProjectService();
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
const locationOfMyConst = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst");
|
||||
const response = session.executeCommandSeq<protocol.RenameRequest>({
|
||||
command: protocol.CommandTypes.Rename,
|
||||
arguments: {
|
||||
file: containerCompositeExec[1].path,
|
||||
...locationOfMyConst
|
||||
}
|
||||
}).response as protocol.RenameResponseBody;
|
||||
|
||||
|
||||
const myConstLen = "myConst".length;
|
||||
const locationOfMyConstInLib = protocolLocationFromSubstring(containerLib[1].content, "myConst");
|
||||
assert.deepEqual(response.locs, [
|
||||
{ file: containerCompositeExec[1].path, locs: [{ start: locationOfMyConst, end: { line: locationOfMyConst.line, offset: locationOfMyConst.offset + myConstLen } }] },
|
||||
{ file: containerLib[1].path, locs: [{ start: locationOfMyConstInLib, end: { line: locationOfMyConstInLib.line, offset: locationOfMyConstInLib.offset + myConstLen } }] }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem duplicate packages", () => {
|
||||
|
||||
@@ -132,6 +132,11 @@ namespace ts {
|
||||
const commandLineOptions = commandLine.options;
|
||||
if (configFileName) {
|
||||
const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic)!; // TODO: GH#18217
|
||||
if (commandLineOptions.showConfig) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
sys.write(JSON.stringify(convertToTSConfig(configParseResult, configFileName, sys), null, 4) + sys.newLine);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
updateReportDiagnostic(configParseResult.options);
|
||||
if (isWatchSet(configParseResult.options)) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
@@ -142,6 +147,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (commandLineOptions.showConfig) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
sys.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(sys.getCurrentDirectory(), "tsconfig.json"), sys), null, 4) + sys.newLine);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
updateReportDiagnostic(commandLineOptions);
|
||||
if (isWatchSet(commandLineOptions)) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of27.ts(1,11): error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of27.ts(1,21): error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of27.ts(1,11): error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of27.ts(1,21): error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-ofStatements/ES5For-of27.ts (2 errors) ====
|
||||
for (var {x: a = 0, y: b = 1} of [2, 3]) {
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
!!! error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
!!! error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
a;
|
||||
b;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of29.ts(1,13): error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of29.ts(1,23): error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of29.ts(1,13): error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of29.ts(1,23): error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-ofStatements/ES5For-of29.ts (2 errors) ====
|
||||
for (const {x: a = 0, y: b = 1} of [2, 3]) {
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
!!! error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
!!! error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
a;
|
||||
b;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of35.ts(1,13): error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of35.ts(1,23): error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of35.ts(1,13): error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-of35.ts(1,23): error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-ofStatements/ES5For-of35.ts (2 errors) ====
|
||||
for (const {x: a = 0, y: b = 1} of [2, 3]) {
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'x' and no string index signature.
|
||||
!!! error TS2339: Property 'x' does not exist on type 'Number'.
|
||||
~
|
||||
!!! error TS2459: Type 'number' has no property 'y' and no string index signature.
|
||||
!!! error TS2339: Property 'y' does not exist on type 'Number'.
|
||||
a;
|
||||
b;
|
||||
}
|
||||
@@ -7486,6 +7486,7 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface DiagnosticEvent extends Event {
|
||||
body?: DiagnosticEventBody;
|
||||
event: DiagnosticEventKind;
|
||||
}
|
||||
interface ConfigFileDiagnosticEventBody {
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Block-scoped variable 'b' used before its declaration.
|
||||
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2538: Type 'any' cannot be used as an index type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (3 errors) ====
|
||||
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (6 errors) ====
|
||||
// 1:
|
||||
for (let {[a]: a} of [{ }]) continue;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:2:16: 'a' is declared here.
|
||||
~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
|
||||
// 2:
|
||||
for (let {[a]: a} = { }; false; ) continue;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:5:16: 'a' is declared here.
|
||||
~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
|
||||
// 3:
|
||||
let {[b]: b} = { };
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'b' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:8:11: 'b' is declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:8:11: 'b' is declared here.
|
||||
~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
@@ -1,33 +1,63 @@
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(3,7): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(8,7): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(10,8): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(11,8): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(14,15): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(15,15): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(16,16): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(17,16): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,8): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: Operator '+' cannot be applied to types '1' and '{}'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (4 errors) ====
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (14 errors) ====
|
||||
// destructuring in variable declarations
|
||||
let foo = "bar";
|
||||
let {[foo]: bar} = {bar: "bar"};
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
let {["bar"]: bar2} = {bar: "bar"};
|
||||
|
||||
let foo2 = () => "bar";
|
||||
let {[foo2()]: bar3} = {bar: "bar"};
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
let [{[foo]: bar4}] = [{bar: "bar"}];
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
let [{[foo2()]: bar5}] = [{bar: "bar"}];
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
function f1({["bar"]: x}: { bar: number }) {}
|
||||
function f2({[foo]: x}: { bar: number }) {}
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f3({[foo2()]: x}: { bar: number }) {}
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f4([{[foo]: x}]: [{ bar: number }]) {}
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f5([{[foo2()]: x}]: [{ bar: number }]) {}
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
|
||||
// report errors on type errors in computed properties used in destructuring
|
||||
let [{[foo()]: bar6}] = [{bar: "bar"}];
|
||||
~~~~~
|
||||
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
~~~~~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
|
||||
|
||||
|
||||
@@ -1,34 +1,64 @@
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(3,7): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(9,7): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(11,8): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(12,8): error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(15,15): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(16,15): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(17,16): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(18,16): error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,8): error TS2538: Type 'any' cannot be used as an index type.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS2365: Operator '+' cannot be applied to types '1' and '{}'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (4 errors) ====
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (14 errors) ====
|
||||
// destructuring in variable declarations
|
||||
let foo = "bar";
|
||||
let {[foo]: bar} = {bar: "bar"};
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
let {["bar"]: bar2} = {bar: "bar"};
|
||||
let {[11]: bar2_1} = {11: "bar"};
|
||||
|
||||
let foo2 = () => "bar";
|
||||
let {[foo2()]: bar3} = {bar: "bar"};
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
let [{[foo]: bar4}] = [{bar: "bar"}];
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
let [{[foo2()]: bar5}] = [{bar: "bar"}];
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: string; }' has no matching index signature for type 'string'.
|
||||
|
||||
function f1({["bar"]: x}: { bar: number }) {}
|
||||
function f2({[foo]: x}: { bar: number }) {}
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f3({[foo2()]: x}: { bar: number }) {}
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f4([{[foo]: x}]: [{ bar: number }]) {}
|
||||
~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
function f5([{[foo2()]: x}]: [{ bar: number }]) {}
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{ bar: number; }' has no matching index signature for type 'string'.
|
||||
|
||||
// report errors on type errors in computed properties used in destructuring
|
||||
let [{[foo()]: bar6}] = [{bar: "bar"}];
|
||||
~~~~~
|
||||
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
|
||||
~~~~~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2538: Type 'any' cannot be used as an index type.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
tests/cases/compiler/computedPropertiesInDestructuring2.ts(2,7): error TS2537: Type '{}' has no matching index signature for type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring2.ts (1 errors) ====
|
||||
let foo2 = () => "bar";
|
||||
let {[foo2()]: bar3} = {};
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{}' has no matching index signature for type 'string'.
|
||||
@@ -0,0 +1,8 @@
|
||||
tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts(2,7): error TS2537: Type '{}' has no matching index signature for type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts (1 errors) ====
|
||||
let foo2 = () => "bar";
|
||||
let {[foo2()]: bar3} = {};
|
||||
~~~~~~
|
||||
!!! error TS2537: Type '{}' has no matching index signature for type 'string'.
|
||||
@@ -15,8 +15,8 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(67,9): e
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(68,9): error TS2461: Type '{ 0: number; 1: number; }' is not an array type.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,14): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2459: Type 'undefined[]' has no property 'a' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2459: Type 'undefined[]' has no property 'b' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2339: Property 'a' does not exist on type 'undefined[]'.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2339: Property 'b' does not exist on type 'undefined[]'.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,17): error TS2322: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'.
|
||||
Property 'x' is missing in type '{ y: boolean; }'.
|
||||
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,6): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
@@ -133,9 +133,9 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9):
|
||||
!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
var { a, b } = []; // Error
|
||||
~
|
||||
!!! error TS2459: Type 'undefined[]' has no property 'a' and no string index signature.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'undefined[]'.
|
||||
~
|
||||
!!! error TS2459: Type 'undefined[]' has no property 'b' and no string index signature.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'undefined[]'.
|
||||
}
|
||||
|
||||
function f11() {
|
||||
|
||||
@@ -18,20 +18,20 @@ class C<T extends Options> {
|
||||
>method : () => void
|
||||
|
||||
let { a, b } = this.foo;
|
||||
>a : T["a"]
|
||||
>b : T["b"]
|
||||
>a : { [P in keyof T]: T[P]; }["a"]
|
||||
>b : { [P in keyof T]: T[P]; }["b"]
|
||||
>this.foo : { [P in keyof T]: T[P]; }
|
||||
>this : this
|
||||
>foo : { [P in keyof T]: T[P]; }
|
||||
|
||||
!(a && b);
|
||||
>!(a && b) : false
|
||||
>(a && b) : T["b"]
|
||||
>a && b : T["b"]
|
||||
>a : T["a"]
|
||||
>b : T["b"]
|
||||
>(a && b) : { [P in keyof T]: T[P]; }["b"]
|
||||
>a && b : { [P in keyof T]: T[P]; }["b"]
|
||||
>a : { [P in keyof T]: T[P]; }["a"]
|
||||
>b : { [P in keyof T]: T[P]; }["b"]
|
||||
|
||||
a;
|
||||
>a : T["a"]
|
||||
>a : { [P in keyof T]: T[P]; }["a"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,7): error TS2459: Type '{ prop: string; }' has no property '[notPresent]' and no string index signature.
|
||||
tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,8): error TS2339: Property 'prop2' does not exist on type '{ prop: string; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts (1 errors) ====
|
||||
@@ -13,6 +13,6 @@ tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,7): error TS
|
||||
const notPresent = "prop2";
|
||||
|
||||
let { [notPresent]: computed2 } = { prop: "b" };
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2459: Type '{ prop: string; }' has no property '[notPresent]' and no string index signature.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2339: Property 'prop2' does not exist on type '{ prop: string; }'.
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//// [destructuredMaappedTypeIsNotImplicitlyAny.ts]
|
||||
function foo<T extends string>(key: T, obj: { [_ in T]: number }) {
|
||||
const { [key]: bar } = obj; // Element implicitly has an 'any' type because type '{ [_ in T]: number; }' has no index signature.
|
||||
bar; // bar : any
|
||||
|
||||
// Note: this does work:
|
||||
const lorem = obj[key];
|
||||
}
|
||||
|
||||
//// [destructuredMaappedTypeIsNotImplicitlyAny.js]
|
||||
function foo(key, obj) {
|
||||
var _a = key, bar = obj[_a]; // Element implicitly has an 'any' type because type '{ [_ in T]: number; }' has no index signature.
|
||||
bar; // bar : any
|
||||
// Note: this does work:
|
||||
var lorem = obj[key];
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
=== tests/cases/compiler/destructuredMaappedTypeIsNotImplicitlyAny.ts ===
|
||||
function foo<T extends string>(key: T, obj: { [_ in T]: number }) {
|
||||
>foo : Symbol(foo, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 13))
|
||||
>key : Symbol(key, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 31))
|
||||
>T : Symbol(T, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 38))
|
||||
>_ : Symbol(_, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 47))
|
||||
>T : Symbol(T, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 13))
|
||||
|
||||
const { [key]: bar } = obj; // Element implicitly has an 'any' type because type '{ [_ in T]: number; }' has no index signature.
|
||||
>key : Symbol(key, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 31))
|
||||
>bar : Symbol(bar, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 1, 11))
|
||||
>obj : Symbol(obj, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 38))
|
||||
|
||||
bar; // bar : any
|
||||
>bar : Symbol(bar, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 1, 11))
|
||||
|
||||
// Note: this does work:
|
||||
const lorem = obj[key];
|
||||
>lorem : Symbol(lorem, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 5, 9))
|
||||
>obj : Symbol(obj, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 38))
|
||||
>key : Symbol(key, Decl(destructuredMaappedTypeIsNotImplicitlyAny.ts, 0, 31))
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
=== tests/cases/compiler/destructuredMaappedTypeIsNotImplicitlyAny.ts ===
|
||||
function foo<T extends string>(key: T, obj: { [_ in T]: number }) {
|
||||
>foo : <T extends string>(key: T, obj: { [_ in T]: number; }) => void
|
||||
>key : T
|
||||
>obj : { [_ in T]: number; }
|
||||
|
||||
const { [key]: bar } = obj; // Element implicitly has an 'any' type because type '{ [_ in T]: number; }' has no index signature.
|
||||
>key : T
|
||||
>bar : { [_ in T]: number; }[T]
|
||||
>obj : { [_ in T]: number; }
|
||||
|
||||
bar; // bar : any
|
||||
>bar : { [_ in T]: number; }[T]
|
||||
|
||||
// Note: this does work:
|
||||
const lorem = obj[key];
|
||||
>lorem : { [_ in T]: number; }[T]
|
||||
>obj[key] : { [_ in T]: number; }[T]
|
||||
>obj : { [_ in T]: number; }
|
||||
>key : T
|
||||
}
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(2,7): error TS1005: ',' expected.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(3,5): error TS2322: Type '{ i: number; }' is not assignable to type 'string | number'.
|
||||
Type '{ i: number; }' is not assignable to type 'number'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(3,6): error TS2459: Type 'string | number' has no property 'i' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(4,6): error TS2459: Type 'string | number | {}' has no property 'i1' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(3,6): error TS2339: Property 'i' does not exist on type 'string | number'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(4,6): error TS2339: Property 'i1' does not exist on type 'string | number | {}'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(5,12): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(5,21): error TS2353: Object literal may only specify known properties, and 'f212' does not exist in type '{ f21: any; }'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(6,7): error TS1005: ':' expected.
|
||||
@@ -20,10 +20,10 @@ tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAs
|
||||
!!! error TS2322: Type '{ i: number; }' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type '{ i: number; }' is not assignable to type 'number'.
|
||||
~
|
||||
!!! error TS2459: Type 'string | number' has no property 'i' and no string index signature.
|
||||
!!! error TS2339: Property 'i' does not exist on type 'string | number'.
|
||||
var {i1}: string | number| {} = { i1: 2 };
|
||||
~~
|
||||
!!! error TS2459: Type 'string | number | {}' has no property 'i1' and no string index signature.
|
||||
!!! error TS2339: Property 'i1' does not exist on type 'string | number | {}'.
|
||||
var { f2: {f21} = { f212: "string" } }: any = undefined;
|
||||
~~~
|
||||
!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,17): error TS1187: A parameter property may not be declared using a binding pattern.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,27): error TS2459: Type 'ObjType1' has no property 'x1' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,31): error TS2459: Type 'ObjType1' has no property 'x2' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,35): error TS2459: Type 'ObjType1' has no property 'x3' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,27): error TS2339: Property 'x1' does not exist on type 'ObjType1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,31): error TS2339: Property 'x2' does not exist on type 'ObjType1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,35): error TS2339: Property 'x3' does not exist on type 'ObjType1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,29): error TS2339: Property 'x1' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,40): error TS2339: Property 'x2' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,51): error TS2339: Property 'x3' does not exist on type 'C1'.
|
||||
@@ -22,11 +22,11 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1187: A parameter property may not be declared using a binding pattern.
|
||||
~~
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x1' and no string index signature.
|
||||
!!! error TS2339: Property 'x1' does not exist on type 'ObjType1'.
|
||||
~~
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x2' and no string index signature.
|
||||
!!! error TS2339: Property 'x2' does not exist on type 'ObjType1'.
|
||||
~~
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x3' and no string index signature.
|
||||
!!! error TS2339: Property 'x3' does not exist on type 'ObjType1'.
|
||||
var foo: any = x1 || x2 || x3 || y || z;
|
||||
var bar: any = this.x1 || this.x2 || this.x3 || this.y || this.z;
|
||||
~~
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
tests/cases/compiler/downlevelLetConst16.ts(151,15): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(164,17): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(195,14): error TS2461: Type 'undefined' is not an array type.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(202,15): error TS2459: Type 'undefined' has no property 'a' and no string index signature.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(202,15): error TS2339: Property 'a' does not exist on type 'undefined'.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(216,16): error TS2461: Type 'undefined' is not an array type.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2459: Type 'undefined' has no property 'a' and no string index signature.
|
||||
tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on type 'undefined'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/downlevelLetConst16.ts (6 errors) ====
|
||||
@@ -216,7 +216,7 @@ tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2459: Type 'undefin
|
||||
function foo9() {
|
||||
for (let {a: x} of []) {
|
||||
~
|
||||
!!! error TS2459: Type 'undefined' has no property 'a' and no string index signature.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'undefined'.
|
||||
use(x);
|
||||
}
|
||||
use(x);
|
||||
@@ -241,7 +241,7 @@ tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2459: Type 'undefin
|
||||
function foo12() {
|
||||
for (const {a: x} of []) {
|
||||
~
|
||||
!!! error TS2459: Type 'undefined' has no property 'a' and no string index signature.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'undefined'.
|
||||
use(x);
|
||||
}
|
||||
use(x);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,10): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,11): error TS2459: Type 'string' has no property 'a' and no string index signature.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,14): error TS2459: Type 'string' has no property 'b' and no string index signature.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,11): error TS2339: Property 'a' does not exist on type 'String'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts(1,14): error TS2339: Property 'b' does not exist on type 'String'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring2.ts (3 errors) ====
|
||||
@@ -8,6 +8,6 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructurin
|
||||
~~~~~~
|
||||
!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern.
|
||||
~
|
||||
!!! error TS2459: Type 'string' has no property 'a' and no string index signature.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'String'.
|
||||
~
|
||||
!!! error TS2459: Type 'string' has no property 'b' and no string index signature.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'String'.
|
||||
@@ -1,6 +1,6 @@
|
||||
tests/cases/conformance/jsdoc/0.js(56,20): error TS8024: JSDoc '@param' tag has name 'obj', but there is no parameter with that name.
|
||||
tests/cases/conformance/jsdoc/0.js(61,19): error TS2459: Type 'string' has no property 'a' and no string index signature.
|
||||
tests/cases/conformance/jsdoc/0.js(61,22): error TS2459: Type 'string' has no property 'b' and no string index signature.
|
||||
tests/cases/conformance/jsdoc/0.js(61,19): error TS2339: Property 'a' does not exist on type 'String'.
|
||||
tests/cases/conformance/jsdoc/0.js(61,22): error TS2339: Property 'b' does not exist on type 'String'.
|
||||
tests/cases/conformance/jsdoc/0.js(63,20): error TS8024: JSDoc '@param' tag has name 'y', but there is no parameter with that name.
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ tests/cases/conformance/jsdoc/0.js(63,20): error TS8024: JSDoc '@param' tag has
|
||||
*/
|
||||
function bad1(x, {a, b}) {}
|
||||
~
|
||||
!!! error TS2459: Type 'string' has no property 'a' and no string index signature.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'String'.
|
||||
~
|
||||
!!! error TS2459: Type 'string' has no property 'b' and no string index signature.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'String'.
|
||||
/**
|
||||
* @param {string} y - here, y's type gets ignored but obj's is fine
|
||||
~
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(2,15): error TS7017: Element implicitly has an 'any' type because type '{ prop: string; }' has no index signature.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(13,15): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(21,15): error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: number]: string; }'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(23,15): error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: string]: string; }'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(25,16): error TS2536: Type 'symbol' cannot be used to index type '{ [idx: number]: string; }'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(27,16): error TS2536: Type 'symbol' cannot be used to index type '{ [idx: string]: string; }'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(2,7): error TS2537: Type '{ prop: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(13,7): error TS2537: Type '{ [idx: number]: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(21,7): error TS2538: Type 'unique symbol' cannot be used as an index type.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(23,7): error TS2538: Type 'unique symbol' cannot be used as an index type.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(25,7): error TS2538: Type 'symbol' cannot be used as an index type.
|
||||
tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(27,7): error TS2538: Type 'symbol' cannot be used as an index type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts (6 errors) ====
|
||||
let named = "foo";
|
||||
let {[named]: prop} = {prop: "foo"};
|
||||
~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{ prop: string; }' has no index signature.
|
||||
~~~~~
|
||||
!!! error TS2537: Type '{ prop: string; }' has no matching index signature for type 'string'.
|
||||
void prop;
|
||||
|
||||
const numIndexed: {[idx: number]: string} = null as any;
|
||||
@@ -22,8 +22,8 @@ tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(27,16): error TS2
|
||||
let symed2 = Symbol();
|
||||
|
||||
let {[named]: prop2} = numIndexed;
|
||||
~~~~~
|
||||
!!! error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
~~~~~
|
||||
!!! error TS2537: Type '{ [idx: number]: string; }' has no matching index signature for type 'string'.
|
||||
void prop2;
|
||||
let {[numed]: prop3} = numIndexed;
|
||||
void prop3;
|
||||
@@ -32,18 +32,18 @@ tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(27,16): error TS2
|
||||
let {[numed]: prop5} = strIndexed;
|
||||
void prop5;
|
||||
let {[symed]: prop6} = numIndexed;
|
||||
~~~~~
|
||||
!!! error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: number]: string; }'.
|
||||
~~~~~
|
||||
!!! error TS2538: Type 'unique symbol' cannot be used as an index type.
|
||||
void prop6;
|
||||
let {[symed]: prop7} = strIndexed;
|
||||
~~~~~
|
||||
!!! error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: string]: string; }'.
|
||||
~~~~~
|
||||
!!! error TS2538: Type 'unique symbol' cannot be used as an index type.
|
||||
void prop7;
|
||||
let {[symed2]: prop8} = numIndexed;
|
||||
~~~~~
|
||||
!!! error TS2536: Type 'symbol' cannot be used to index type '{ [idx: number]: string; }'.
|
||||
~~~~~~
|
||||
!!! error TS2538: Type 'symbol' cannot be used as an index type.
|
||||
void prop8;
|
||||
let {[symed2]: prop9} = strIndexed;
|
||||
~~~~~
|
||||
!!! error TS2536: Type 'symbol' cannot be used to index type '{ [idx: string]: string; }'.
|
||||
~~~~~~
|
||||
!!! error TS2538: Type 'symbol' cannot be used as an index type.
|
||||
void prop9;
|
||||
@@ -87,12 +87,12 @@ void prop6;
|
||||
|
||||
let {[symed]: prop7} = strIndexed;
|
||||
>symed : unique symbol
|
||||
>prop7 : any
|
||||
>prop7 : string
|
||||
>strIndexed : { [idx: string]: string; }
|
||||
|
||||
void prop7;
|
||||
>void prop7 : undefined
|
||||
>prop7 : any
|
||||
>prop7 : string
|
||||
|
||||
let {[symed2]: prop8} = numIndexed;
|
||||
>symed2 : symbol
|
||||
@@ -105,10 +105,10 @@ void prop8;
|
||||
|
||||
let {[symed2]: prop9} = strIndexed;
|
||||
>symed2 : symbol
|
||||
>prop9 : any
|
||||
>prop9 : string
|
||||
>strIndexed : { [idx: string]: string; }
|
||||
|
||||
void prop9;
|
||||
>void prop9 : undefined
|
||||
>prop9 : any
|
||||
>prop9 : string
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(3,3): error TS2339: Property 'nonExist' does not exist on type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(5,7): error TS2459: Type 'object' has no property 'destructuring' and no string index signature.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(5,7): error TS2339: Property 'destructuring' does not exist on type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (2 errors) ====
|
||||
@@ -11,6 +11,6 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(5,7): e
|
||||
|
||||
var { destructuring } = a; // error
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2459: Type 'object' has no property 'destructuring' and no string index signature.
|
||||
!!! error TS2339: Property 'destructuring' does not exist on type '{}'.
|
||||
var { ...rest } = a; // ok
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
tests/cases/conformance/types/rest/objectRest.ts(7,12): error TS2339: Property '0' does not exist on type 'String'.
|
||||
tests/cases/conformance/types/rest/objectRest.ts(7,20): error TS2339: Property '1' does not exist on type 'String'.
|
||||
tests/cases/conformance/types/rest/objectRest.ts(43,8): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/conformance/types/rest/objectRest.ts(43,35): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'.
|
||||
tests/cases/conformance/types/rest/objectRest.ts(43,57): error TS2403: Subsequent variable declarations must have the same type. Variable 'o' must be of type '{ a: number; b: string; }', but here has type 'Rest<{ a: number; b: string; }, string>'.
|
||||
tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2322: Type 'Rest<{ a: number; b: string; }, string>' is not assignable to type '{ a: number; b: string; }'.
|
||||
Property 'a' is missing in type 'Rest<{ a: number; b: string; }, string>'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/objectRest.ts (2 errors) ====
|
||||
==== tests/cases/conformance/types/rest/objectRest.ts (6 errors) ====
|
||||
var o = { a: 1, b: 'no' }
|
||||
var { ...clone } = o;
|
||||
var { a, ...justB } = o;
|
||||
@@ -11,6 +15,10 @@ tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2322: Type 'Res
|
||||
var { ['b']: renamed, ...justA } = o;
|
||||
var { 'b': renamed, ...justA } = o;
|
||||
var { b: { '0': n, '1': oooo }, ...justA } = o;
|
||||
~~~
|
||||
!!! error TS2339: Property '0' does not exist on type 'String'.
|
||||
~~~
|
||||
!!! error TS2339: Property '1' does not exist on type 'String'.
|
||||
|
||||
let o2 = { c: 'terrible idea?', d: 'yes' };
|
||||
var { d: renamed, ...d } = o2;
|
||||
@@ -47,6 +55,10 @@ tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2322: Type 'Res
|
||||
let computed = 'b';
|
||||
let computed2 = 'a';
|
||||
var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
|
||||
~~~~~~~~
|
||||
!!! error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'.
|
||||
~~~~~~~~~
|
||||
!!! error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'.
|
||||
~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o' must be of type '{ a: number; b: string; }', but here has type 'Rest<{ a: number; b: string; }, string>'.
|
||||
({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o);
|
||||
|
||||
@@ -36,8 +36,8 @@ var { 'b': renamed, ...justA } = o;
|
||||
|
||||
var { b: { '0': n, '1': oooo }, ...justA } = o;
|
||||
>b : any
|
||||
>n : string
|
||||
>oooo : string
|
||||
>n : any
|
||||
>oooo : any
|
||||
>justA : Rest<{ a: number; b: string; }, "b">
|
||||
>o : { a: number; b: string; }
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
|
||||
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer.
|
||||
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer.
|
||||
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2537: Type 'any[]' has no matching index signature for type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (3 errors) ====
|
||||
==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (4 errors) ====
|
||||
let foo: string = "";
|
||||
|
||||
function f1 (bar = foo) { // unexpected compiler error; works at runtime
|
||||
@@ -39,6 +40,8 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t
|
||||
}
|
||||
|
||||
function f7({[foo]: bar}: any[]) {
|
||||
~~~
|
||||
!!! error TS2537: Type 'any[]' has no matching index signature for type 'string'.
|
||||
let foo: number = 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
tests/cases/conformance/es6/destructuring/restElementWithBindingPattern2.ts(1,16): error TS2459: Type 'number[]' has no property 'b' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/restElementWithBindingPattern2.ts(1,16): error TS2339: Property 'b' does not exist on type 'number[]'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/restElementWithBindingPattern2.ts (1 errors) ====
|
||||
var [...{0: a, b }] = [0, 1];
|
||||
~
|
||||
!!! error TS2459: Type 'number[]' has no property 'b' and no string index signature.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'number[]'.
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"compilerOptions": {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationDir": "./lib",
|
||||
"skipLibCheck": true,
|
||||
"noErrorTruncation": true
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noUnusedLocals": true
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"jsx": "react"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"compilerOptions": {}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es5",
|
||||
"es2015.promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"compilerOptions": {}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es5",
|
||||
"es2015.core"
|
||||
]
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"jquery",
|
||||
"mocha"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// @noImplicitAny: true
|
||||
function foo<T extends string>(key: T, obj: { [_ in T]: number }) {
|
||||
const { [key]: bar } = obj; // Element implicitly has an 'any' type because type '{ [_ in T]: number; }' has no index signature.
|
||||
bar; // bar : any
|
||||
|
||||
// Note: this does work:
|
||||
const lorem = obj[key];
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outFile": "../built/local/compositeExec.js",
|
||||
"composite": true
|
||||
"composite": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"files": [
|
||||
"index.ts"
|
||||
|
||||
Reference in New Issue
Block a user