mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into incrementalLateSymbol
This commit is contained in:
@@ -236,10 +236,7 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
|
||||
if (oldCompilerOptions &&
|
||||
(oldCompilerOptions.outDir !== compilerOptions.outDir ||
|
||||
oldCompilerOptions.declarationDir !== compilerOptions.declarationDir ||
|
||||
(oldCompilerOptions.outFile || oldCompilerOptions.out) !== (compilerOptions.outFile || compilerOptions.out))) {
|
||||
if (oldCompilerOptions && compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) {
|
||||
// Add all files to affectedFilesPendingEmit since emit changed
|
||||
state.affectedFilesPendingEmit = concatenate(state.affectedFilesPendingEmit, newProgram.getSourceFiles().map(f => f.path));
|
||||
if (state.affectedFilesPendingEmitIndex === undefined) {
|
||||
|
||||
+66
-46
@@ -114,6 +114,11 @@ namespace ts {
|
||||
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
|
||||
getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount,
|
||||
getTypeCount: () => typeCount,
|
||||
getRelationCacheSizes: () => ({
|
||||
assignable: assignableRelation.size,
|
||||
identity: identityRelation.size,
|
||||
subtype: subtypeRelation.size,
|
||||
}),
|
||||
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
|
||||
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
|
||||
isUnknownSymbol: symbol => symbol === unknownSymbol,
|
||||
@@ -7474,6 +7479,25 @@ namespace ts {
|
||||
return type.resolvedProperties;
|
||||
}
|
||||
|
||||
function getPossiblePropertiesOfUnionType(type: UnionType): Symbol[] {
|
||||
if (type.possiblePropertyCache) {
|
||||
return type.possiblePropertyCache.size ? arrayFrom(type.possiblePropertyCache.values()) : emptyArray;
|
||||
}
|
||||
type.possiblePropertyCache = createSymbolTable();
|
||||
for (const t of type.types) {
|
||||
for (const p of getPropertiesOfType(t)) {
|
||||
if (!type.possiblePropertyCache.has(p.escapedName)) {
|
||||
const prop = getUnionOrIntersectionProperty(type, p.escapedName);
|
||||
if (prop) {
|
||||
type.possiblePropertyCache.set(p.escapedName, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We can't simply use the normal property cache here, since that will contain cached apparent type members :(
|
||||
return type.possiblePropertyCache.size ? arrayFrom(type.possiblePropertyCache.values()) : emptyArray;
|
||||
}
|
||||
|
||||
function getPropertiesOfType(type: Type): Symbol[] {
|
||||
type = getApparentType(type);
|
||||
return type.flags & TypeFlags.UnionOrIntersection ?
|
||||
@@ -7831,7 +7855,7 @@ namespace ts {
|
||||
const isUnion = containingType.flags & TypeFlags.Union;
|
||||
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
|
||||
// Flags we want to propagate to the result if they exist in all source symbols
|
||||
let commonFlags = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
|
||||
let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
|
||||
let syntheticFlag = CheckFlags.SyntheticMethod;
|
||||
let checkFlags = 0;
|
||||
for (const current of containingType.types) {
|
||||
@@ -7840,7 +7864,12 @@ namespace ts {
|
||||
const prop = getPropertyOfType(type, name);
|
||||
const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0;
|
||||
if (prop && !(modifiers & excludeModifiers)) {
|
||||
commonFlags &= prop.flags;
|
||||
if (isUnion) {
|
||||
optionalFlag |= (prop.flags & SymbolFlags.Optional);
|
||||
}
|
||||
else {
|
||||
optionalFlag &= prop.flags;
|
||||
}
|
||||
const id = "" + getSymbolId(prop);
|
||||
if (!propSet.has(id)) {
|
||||
propSet.set(id, prop);
|
||||
@@ -7858,10 +7887,11 @@ namespace ts {
|
||||
const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String));
|
||||
if (indexInfo) {
|
||||
checkFlags |= indexInfo.isReadonly ? CheckFlags.Readonly : 0;
|
||||
checkFlags |= CheckFlags.WritePartial;
|
||||
indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
|
||||
}
|
||||
else {
|
||||
checkFlags |= CheckFlags.Partial;
|
||||
checkFlags |= CheckFlags.ReadPartial;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7870,7 +7900,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
const props = arrayFrom(propSet.values());
|
||||
if (props.length === 1 && !(checkFlags & CheckFlags.Partial) && !indexTypes) {
|
||||
if (props.length === 1 && !(checkFlags & CheckFlags.ReadPartial) && !indexTypes) {
|
||||
return props[0];
|
||||
}
|
||||
let declarations: Declaration[] | undefined;
|
||||
@@ -7901,7 +7931,7 @@ namespace ts {
|
||||
propTypes.push(type);
|
||||
}
|
||||
addRange(propTypes, indexTypes);
|
||||
const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags);
|
||||
const result = createSymbol(SymbolFlags.Property | optionalFlag, name, syntheticFlag | checkFlags);
|
||||
result.containingType = containingType;
|
||||
if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
|
||||
result.valueDeclaration = firstValueDeclaration;
|
||||
@@ -7938,7 +7968,7 @@ namespace ts {
|
||||
function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: __String): Symbol | undefined {
|
||||
const property = getUnionOrIntersectionProperty(type, name);
|
||||
// We need to filter out partial properties in union types
|
||||
return property && !(getCheckFlags(property) & CheckFlags.Partial) ? property : undefined;
|
||||
return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12277,25 +12307,6 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function isUnionOrIntersectionTypeWithoutNullableConstituents(type: Type): boolean {
|
||||
if (!(type.flags & TypeFlags.UnionOrIntersection)) {
|
||||
return false;
|
||||
}
|
||||
// at this point we know that this is union or intersection type possibly with nullable constituents.
|
||||
// check if we still will have compound type if we ignore nullable components.
|
||||
let seenNonNullable = false;
|
||||
for (const t of (<UnionOrIntersectionType>type).types) {
|
||||
if (t.flags & TypeFlags.Nullable) {
|
||||
continue;
|
||||
}
|
||||
if (seenNonNullable) {
|
||||
return true;
|
||||
}
|
||||
seenNonNullable = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two types and return
|
||||
* * Ternary.True if they are related with no assumptions,
|
||||
@@ -12350,7 +12361,8 @@ namespace ts {
|
||||
isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
|
||||
if (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral) {
|
||||
const isPerformingExcessPropertyChecks = (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral);
|
||||
if (isPerformingExcessPropertyChecks) {
|
||||
const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, discriminantType, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
@@ -12358,13 +12370,6 @@ namespace ts {
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
// Above we check for excess properties with respect to the entire target type. When union
|
||||
// and intersection types are further deconstructed on the target side, we don't want to
|
||||
// make the check again (as it might fail for a partial target type). Therefore we obtain
|
||||
// the regular source type and proceed with that.
|
||||
if (isUnionOrIntersectionTypeWithoutNullableConstituents(target) && !discriminantType) {
|
||||
source = getRegularTypeOfObjectLiteral(source);
|
||||
}
|
||||
}
|
||||
|
||||
if (relation !== comparableRelation && !isApparentIntersectionConstituent &&
|
||||
@@ -12400,11 +12405,24 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
result = typeRelatedToSomeType(source, <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
|
||||
result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
|
||||
if (result && isPerformingExcessPropertyChecks) {
|
||||
// Validate against excess props using the original `source`
|
||||
const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
|
||||
if (!propertiesRelatedTo(source, discriminantType || target, reportErrors)) {
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Intersection) {
|
||||
isIntersectionConstituent = true; // set here to affect the following trio of checks
|
||||
result = typeRelatedToEachType(source, target as IntersectionType, reportErrors);
|
||||
result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors);
|
||||
if (result && isPerformingExcessPropertyChecks) {
|
||||
// Validate against excess props using the original `source`
|
||||
if (!propertiesRelatedTo(source, target, reportErrors)) {
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.Intersection) {
|
||||
// Check to see if any constituents of the intersection are immediately related to the target.
|
||||
@@ -12507,7 +12525,7 @@ namespace ts {
|
||||
// check excess properties against discriminant type only, not the entire union
|
||||
return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors);
|
||||
}
|
||||
for (const prop of getPropertiesOfObjectType(source)) {
|
||||
for (const prop of getPropertiesOfType(source)) {
|
||||
if (shouldCheckAsExcessProperty(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
|
||||
if (reportErrors) {
|
||||
// Report error in terms of object types in the target as those are the only ones
|
||||
@@ -13234,7 +13252,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
// We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_
|
||||
// from the target union, across all members
|
||||
const properties = target.flags & TypeFlags.Union ? getPossiblePropertiesOfUnionType(target as UnionType) : getPropertiesOfType(target);
|
||||
for (const targetProp of properties) {
|
||||
if (!(targetProp.flags & SymbolFlags.Prototype)) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
@@ -13282,7 +13302,8 @@ namespace ts {
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
const related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors);
|
||||
// If the target comes from a partial union prop, allow `undefined` in the target type
|
||||
const related = isRelatedTo(getTypeOfSymbol(sourceProp), addOptionality(getTypeOfSymbol(targetProp), !!(getCheckFlags(targetProp) & CheckFlags.Partial)), reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
|
||||
@@ -14628,9 +14649,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean) {
|
||||
const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(<IntersectionType>target) : getPropertiesOfObjectType(target);
|
||||
const properties = target.flags & TypeFlags.Union ? getPossiblePropertiesOfUnionType(target as UnionType) : getPropertiesOfType(target);
|
||||
for (const targetProp of properties) {
|
||||
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
|
||||
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional || getCheckFlags(targetProp) & CheckFlags.Partial)) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (!sourceProp) {
|
||||
yield targetProp;
|
||||
@@ -15001,12 +15022,11 @@ namespace ts {
|
||||
}
|
||||
// If no inferences can be made to K's constraint, infer from a union of the property types
|
||||
// in the source to the template type X.
|
||||
const valueTypes = compact([
|
||||
getIndexTypeOfType(source, IndexKind.String),
|
||||
getIndexTypeOfType(source, IndexKind.Number),
|
||||
...map(getPropertiesOfType(source), getTypeOfSymbol)
|
||||
]);
|
||||
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target));
|
||||
const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol);
|
||||
const stringIndexType = getIndexTypeOfType(source, IndexKind.String);
|
||||
const numberIndexInfo = getNonEnumNumberIndexInfo(source);
|
||||
const numberIndexType = numberIndexInfo && numberIndexInfo.type;
|
||||
inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -281,6 +281,7 @@ namespace ts {
|
||||
name: "declaration",
|
||||
shortName: "d",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Generates_corresponding_d_ts_file,
|
||||
@@ -288,6 +289,7 @@ namespace ts {
|
||||
{
|
||||
name: "declarationMap",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Generates_a_sourcemap_for_each_corresponding_d_ts_file,
|
||||
@@ -295,12 +297,14 @@ namespace ts {
|
||||
{
|
||||
name: "emitDeclarationOnly",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Only_emit_d_ts_declaration_files,
|
||||
},
|
||||
{
|
||||
name: "sourceMap",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Generates_corresponding_map_file,
|
||||
@@ -308,6 +312,7 @@ namespace ts {
|
||||
{
|
||||
name: "outFile",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: true,
|
||||
paramType: Diagnostics.FILE,
|
||||
showInSimplifiedHelpView: true,
|
||||
@@ -317,6 +322,7 @@ namespace ts {
|
||||
{
|
||||
name: "outDir",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: true,
|
||||
paramType: Diagnostics.DIRECTORY,
|
||||
showInSimplifiedHelpView: true,
|
||||
@@ -326,6 +332,7 @@ namespace ts {
|
||||
{
|
||||
name: "rootDir",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: true,
|
||||
paramType: Diagnostics.LOCATION,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@@ -334,6 +341,7 @@ namespace ts {
|
||||
{
|
||||
name: "composite",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
isTSConfigOnly: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Enable_project_compilation,
|
||||
@@ -341,6 +349,7 @@ namespace ts {
|
||||
{
|
||||
name: "tsBuildInfoFile",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: true,
|
||||
paramType: Diagnostics.FILE,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@@ -349,6 +358,7 @@ namespace ts {
|
||||
{
|
||||
name: "removeComments",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Do_not_emit_comments_to_output,
|
||||
@@ -356,6 +366,7 @@ namespace ts {
|
||||
{
|
||||
name: "noEmit",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Do_not_emit_outputs,
|
||||
@@ -363,12 +374,14 @@ namespace ts {
|
||||
{
|
||||
name: "importHelpers",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Import_emit_helpers_from_tslib
|
||||
},
|
||||
{
|
||||
name: "downlevelIteration",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
|
||||
},
|
||||
@@ -580,6 +593,7 @@ namespace ts {
|
||||
{
|
||||
name: "sourceRoot",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
paramType: Diagnostics.LOCATION,
|
||||
category: Diagnostics.Source_Map_Options,
|
||||
description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
|
||||
@@ -587,6 +601,7 @@ namespace ts {
|
||||
{
|
||||
name: "mapRoot",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
paramType: Diagnostics.LOCATION,
|
||||
category: Diagnostics.Source_Map_Options,
|
||||
description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
|
||||
@@ -594,12 +609,14 @@ namespace ts {
|
||||
{
|
||||
name: "inlineSourceMap",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Source_Map_Options,
|
||||
description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
|
||||
},
|
||||
{
|
||||
name: "inlineSources",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Source_Map_Options,
|
||||
description: Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
|
||||
},
|
||||
@@ -635,6 +652,7 @@ namespace ts {
|
||||
{
|
||||
name: "out",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files
|
||||
// for correct behaviour, please use outFile
|
||||
category: Diagnostics.Advanced_Options,
|
||||
@@ -644,6 +662,7 @@ namespace ts {
|
||||
{
|
||||
name: "reactNamespace",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
|
||||
},
|
||||
@@ -662,6 +681,7 @@ namespace ts {
|
||||
{
|
||||
name: "emitBOM",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
|
||||
},
|
||||
@@ -677,6 +697,7 @@ namespace ts {
|
||||
crlf: NewLineKind.CarriageReturnLineFeed,
|
||||
lf: NewLineKind.LineFeed
|
||||
}),
|
||||
affectsEmit: true,
|
||||
paramType: Diagnostics.NEWLINE,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
|
||||
@@ -704,6 +725,7 @@ namespace ts {
|
||||
{
|
||||
name: "stripInternal",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
|
||||
},
|
||||
@@ -724,24 +746,28 @@ namespace ts {
|
||||
{
|
||||
name: "noEmitHelpers",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
|
||||
},
|
||||
{
|
||||
name: "noEmitOnError",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
|
||||
},
|
||||
{
|
||||
name: "preserveConstEnums",
|
||||
type: "boolean",
|
||||
affectsEmit: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
|
||||
},
|
||||
{
|
||||
name: "declarationDir",
|
||||
type: "string",
|
||||
affectsEmit: true,
|
||||
isFilePath: true,
|
||||
paramType: Diagnostics.DIRECTORY,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
@@ -826,6 +852,10 @@ namespace ts {
|
||||
export const semanticDiagnosticsOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics);
|
||||
|
||||
/* @internal */
|
||||
export const affectsEmitOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsEmit);
|
||||
|
||||
/* @internal */
|
||||
export const moduleResolutionOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsModuleResolution);
|
||||
|
||||
@@ -927,6 +927,7 @@ namespace ts {
|
||||
getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(),
|
||||
getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(),
|
||||
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
|
||||
getRelationCacheSizes: () => getDiagnosticsProducingTypeChecker().getRelationCacheSizes(),
|
||||
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
|
||||
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
|
||||
isSourceFileFromExternalLibrary,
|
||||
|
||||
+19
-12
@@ -2961,6 +2961,7 @@ namespace ts {
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
/* @internal */ getSymbolCount(): number;
|
||||
/* @internal */ getTypeCount(): number;
|
||||
/* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number };
|
||||
|
||||
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
|
||||
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective | undefined>;
|
||||
@@ -3246,6 +3247,7 @@ namespace ts {
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
/* @internal */ getSymbolCount(): number;
|
||||
/* @internal */ getTypeCount(): number;
|
||||
/* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number };
|
||||
|
||||
/* @internal */ isArrayType(type: Type): boolean;
|
||||
/* @internal */ isTupleType(type: Type): boolean;
|
||||
@@ -3746,19 +3748,21 @@ namespace ts {
|
||||
SyntheticProperty = 1 << 1, // Property in union or intersection type
|
||||
SyntheticMethod = 1 << 2, // Method in union or intersection type
|
||||
Readonly = 1 << 3, // Readonly transient symbol
|
||||
Partial = 1 << 4, // Synthetic property present in some but not all constituents
|
||||
HasNonUniformType = 1 << 5, // Synthetic property with non-uniform type in constituents
|
||||
HasLiteralType = 1 << 6, // Synthetic property with at least one literal type in constituents
|
||||
ContainsPublic = 1 << 7, // Synthetic property with public constituent(s)
|
||||
ContainsProtected = 1 << 8, // Synthetic property with protected constituent(s)
|
||||
ContainsPrivate = 1 << 9, // Synthetic property with private constituent(s)
|
||||
ContainsStatic = 1 << 10, // Synthetic property with static constituent(s)
|
||||
Late = 1 << 11, // Late-bound symbol for a computed property with a dynamic name
|
||||
ReverseMapped = 1 << 12, // Property of reverse-inferred homomorphic mapped type
|
||||
OptionalParameter = 1 << 13, // Optional parameter
|
||||
RestParameter = 1 << 14, // Rest parameter
|
||||
ReadPartial = 1 << 4, // Synthetic property present in some but not all constituents
|
||||
WritePartial = 1 << 5, // Synthetic property present in some but only satisfied by an index signature in others
|
||||
HasNonUniformType = 1 << 6, // Synthetic property with non-uniform type in constituents
|
||||
HasLiteralType = 1 << 7, // Synthetic property with at least one literal type in constituents
|
||||
ContainsPublic = 1 << 8, // Synthetic property with public constituent(s)
|
||||
ContainsProtected = 1 << 9, // Synthetic property with protected constituent(s)
|
||||
ContainsPrivate = 1 << 10, // Synthetic property with private constituent(s)
|
||||
ContainsStatic = 1 << 11, // Synthetic property with static constituent(s)
|
||||
Late = 1 << 12, // Late-bound symbol for a computed property with a dynamic name
|
||||
ReverseMapped = 1 << 13, // Property of reverse-inferred homomorphic mapped type
|
||||
OptionalParameter = 1 << 14, // Optional parameter
|
||||
RestParameter = 1 << 15, // Rest parameter
|
||||
Synthetic = SyntheticProperty | SyntheticMethod,
|
||||
Discriminant = HasNonUniformType | HasLiteralType
|
||||
Discriminant = HasNonUniformType | HasLiteralType,
|
||||
Partial = ReadPartial | WritePartial
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4171,6 +4175,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface UnionType extends UnionOrIntersectionType {
|
||||
/* @internal */
|
||||
possiblePropertyCache?: SymbolTable; // Cache of _all_ resolved properties less any from aparent members
|
||||
}
|
||||
|
||||
export interface IntersectionType extends UnionOrIntersectionType {
|
||||
@@ -4823,6 +4829,7 @@ namespace ts {
|
||||
affectsModuleResolution?: true; // currently same effect as `affectsSourceFile`
|
||||
affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`)
|
||||
affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics
|
||||
affectsEmit?: true; // true if the options affects emit
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -7320,6 +7320,11 @@ namespace ts {
|
||||
semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
|
||||
}
|
||||
|
||||
export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
|
||||
return oldOptions !== newOptions &&
|
||||
affectsEmitOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
|
||||
}
|
||||
|
||||
export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown {
|
||||
return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name];
|
||||
}
|
||||
|
||||
@@ -720,6 +720,47 @@ class someClass { }`),
|
||||
"/src/tests/tsconfig.tsbuildinfo",
|
||||
]
|
||||
});
|
||||
|
||||
verifyTsbuildOutput({
|
||||
scenario: "when declaration option changes",
|
||||
projFs: () => projFs,
|
||||
time,
|
||||
tick,
|
||||
proj: "sample1",
|
||||
rootNames: ["/src/core"],
|
||||
expectedMapFileNames: emptyArray,
|
||||
lastProjectOutputJs: "/src/core/index.js",
|
||||
initialBuild: {
|
||||
modifyFs: fs => fs.writeFileSync("/src/core/tsconfig.json", `{
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"skipDefaultLibCheck": true
|
||||
}
|
||||
}`),
|
||||
expectedDiagnostics: [
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
|
||||
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
|
||||
]
|
||||
},
|
||||
incrementalDtsChangedBuild: {
|
||||
modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"incremental": true,`, `"incremental": true, "declaration": true,`),
|
||||
expectedDiagnostics: [
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.d.ts"],
|
||||
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"]
|
||||
]
|
||||
},
|
||||
outputFiles: [
|
||||
"/src/core/anotherModule.js",
|
||||
"/src/core/anotherModule.d.ts",
|
||||
"/src/core/index.js",
|
||||
"/src/core/index.d.ts",
|
||||
"/src/core/tsconfig.tsbuildinfo",
|
||||
],
|
||||
baselineOnly: true,
|
||||
verifyDiagnostics: true
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -340,6 +340,10 @@ namespace ts {
|
||||
const checkTime = performance.getDuration("Check");
|
||||
const emitTime = performance.getDuration("Emit");
|
||||
if (compilerOptions.extendedDiagnostics) {
|
||||
const caches = program.getRelationCacheSizes();
|
||||
reportCountStatistic("Assignability cache size", caches.assignable);
|
||||
reportCountStatistic("Identity cache size", caches.identity);
|
||||
reportCountStatistic("Subtype cache size", caches.subtype);
|
||||
performance.forEachMeasure((name, duration) => reportTimeStatistic(`${name} time`, duration));
|
||||
}
|
||||
else {
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(21,33): error TS2322: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'.
|
||||
Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'.
|
||||
tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(27,34): error TS2326: Types of property 'icon' are incompatible.
|
||||
Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp<ITestProps>'.
|
||||
Types of property 'props' are incompatible.
|
||||
Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'.
|
||||
Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts (2 errors) ====
|
||||
interface StatelessComponent<P = {}> {
|
||||
(props: P & { children?: number }, context?: any): null;
|
||||
}
|
||||
|
||||
const TestComponent: StatelessComponent<TestProps> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
interface ITestProps {
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
interface NestedProp<TProps> {
|
||||
props: TProps;
|
||||
}
|
||||
|
||||
interface TestProps {
|
||||
icon: NestedProp<ITestProps>;
|
||||
}
|
||||
|
||||
TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'.
|
||||
!!! related TS6500 tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts:14:3: The expected type comes from property 'props' which is declared here on type 'NestedProp<ITestProps>'
|
||||
|
||||
const TestComponent2: StatelessComponent<TestProps | {props2: {x: number}}> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2326: Types of property 'icon' are incompatible.
|
||||
!!! error TS2326: Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp<ITestProps>'.
|
||||
!!! error TS2326: Types of property 'props' are incompatible.
|
||||
!!! error TS2326: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'.
|
||||
!!! error TS2326: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//// [deepExcessPropertyCheckingWhenTargetIsIntersection.ts]
|
||||
interface StatelessComponent<P = {}> {
|
||||
(props: P & { children?: number }, context?: any): null;
|
||||
}
|
||||
|
||||
const TestComponent: StatelessComponent<TestProps> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
interface ITestProps {
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
interface NestedProp<TProps> {
|
||||
props: TProps;
|
||||
}
|
||||
|
||||
interface TestProps {
|
||||
icon: NestedProp<ITestProps>;
|
||||
}
|
||||
|
||||
TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
|
||||
const TestComponent2: StatelessComponent<TestProps | {props2: {x: number}}> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
|
||||
|
||||
//// [deepExcessPropertyCheckingWhenTargetIsIntersection.js]
|
||||
var TestComponent = function (props) {
|
||||
return null;
|
||||
};
|
||||
TestComponent({ icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } });
|
||||
var TestComponent2 = function (props) {
|
||||
return null;
|
||||
};
|
||||
TestComponent2({ icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } });
|
||||
@@ -0,0 +1,71 @@
|
||||
=== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts ===
|
||||
interface StatelessComponent<P = {}> {
|
||||
>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 29))
|
||||
|
||||
(props: P & { children?: number }, context?: any): null;
|
||||
>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 3))
|
||||
>P : Symbol(P, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 29))
|
||||
>children : Symbol(children, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 15))
|
||||
>context : Symbol(context, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 1, 36))
|
||||
}
|
||||
|
||||
const TestComponent: StatelessComponent<TestProps> = (props) => {
|
||||
>TestComponent : Symbol(TestComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 5))
|
||||
>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0))
|
||||
>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1))
|
||||
>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 54))
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
interface ITestProps {
|
||||
>ITestProps : Symbol(ITestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 6, 1))
|
||||
|
||||
ariaLabel?: string;
|
||||
>ariaLabel : Symbol(ITestProps.ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 8, 22))
|
||||
}
|
||||
|
||||
interface NestedProp<TProps> {
|
||||
>NestedProp : Symbol(NestedProp, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 10, 1))
|
||||
>TProps : Symbol(TProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 21))
|
||||
|
||||
props: TProps;
|
||||
>props : Symbol(NestedProp.props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 30))
|
||||
>TProps : Symbol(TProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 12, 21))
|
||||
}
|
||||
|
||||
interface TestProps {
|
||||
>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1))
|
||||
|
||||
icon: NestedProp<ITestProps>;
|
||||
>icon : Symbol(TestProps.icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 16, 21))
|
||||
>NestedProp : Symbol(NestedProp, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 10, 1))
|
||||
>ITestProps : Symbol(ITestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 6, 1))
|
||||
}
|
||||
|
||||
TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
>TestComponent : Symbol(TestComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 4, 5))
|
||||
>icon : Symbol(icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 15))
|
||||
>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 22))
|
||||
>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 31))
|
||||
>ariaLabel : Symbol(ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 20, 59))
|
||||
|
||||
const TestComponent2: StatelessComponent<TestProps | {props2: {x: number}}> = (props) => {
|
||||
>TestComponent2 : Symbol(TestComponent2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 5))
|
||||
>StatelessComponent : Symbol(StatelessComponent, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 0, 0))
|
||||
>TestProps : Symbol(TestProps, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 14, 1))
|
||||
>props2 : Symbol(props2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 54))
|
||||
>x : Symbol(x, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 63))
|
||||
>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 79))
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
>TestComponent2 : Symbol(TestComponent2, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 22, 5))
|
||||
>icon : Symbol(icon, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 16))
|
||||
>props : Symbol(props, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 23))
|
||||
>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 32))
|
||||
>ariaLabel : Symbol(ariaLabel, Decl(deepExcessPropertyCheckingWhenTargetIsIntersection.ts, 26, 60))
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
=== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts ===
|
||||
interface StatelessComponent<P = {}> {
|
||||
(props: P & { children?: number }, context?: any): null;
|
||||
>props : P & { children?: number; }
|
||||
>children : number
|
||||
>context : any
|
||||
>null : null
|
||||
}
|
||||
|
||||
const TestComponent: StatelessComponent<TestProps> = (props) => {
|
||||
>TestComponent : StatelessComponent<TestProps>
|
||||
>(props) => { return null;} : (props: TestProps & { children?: number; }) => any
|
||||
>props : TestProps & { children?: number; }
|
||||
|
||||
return null;
|
||||
>null : null
|
||||
}
|
||||
|
||||
interface ITestProps {
|
||||
ariaLabel?: string;
|
||||
>ariaLabel : string
|
||||
}
|
||||
|
||||
interface NestedProp<TProps> {
|
||||
props: TProps;
|
||||
>props : TProps
|
||||
}
|
||||
|
||||
interface TestProps {
|
||||
icon: NestedProp<ITestProps>;
|
||||
>icon : NestedProp<ITestProps>
|
||||
}
|
||||
|
||||
TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
>TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}) : null
|
||||
>TestComponent : StatelessComponent<TestProps>
|
||||
>{icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }} : { icon: { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }; }
|
||||
>icon : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }
|
||||
>{ props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }
|
||||
>props : { INVALID_PROP_NAME: string; ariaLabel: string; }
|
||||
>{ INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } : { INVALID_PROP_NAME: string; ariaLabel: string; }
|
||||
>INVALID_PROP_NAME : string
|
||||
>'share' : "share"
|
||||
>ariaLabel : string
|
||||
>'test label' : "test label"
|
||||
|
||||
const TestComponent2: StatelessComponent<TestProps | {props2: {x: number}}> = (props) => {
|
||||
>TestComponent2 : StatelessComponent<TestProps | { props2: { x: number; }; }>
|
||||
>props2 : { x: number; }
|
||||
>x : number
|
||||
>(props) => { return null;} : (props: (TestProps & { children?: number; }) | ({ props2: { x: number; }; } & { children?: number; })) => any
|
||||
>props : (TestProps & { children?: number; }) | ({ props2: { x: number; }; } & { children?: number; })
|
||||
|
||||
return null;
|
||||
>null : null
|
||||
}
|
||||
|
||||
TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
>TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}) : null
|
||||
>TestComponent2 : StatelessComponent<TestProps | { props2: { x: number; }; }>
|
||||
>{icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }} : { icon: { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }; }
|
||||
>icon : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }
|
||||
>{ props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } } : { props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }
|
||||
>props : { INVALID_PROP_NAME: string; ariaLabel: string; }
|
||||
>{ INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } : { INVALID_PROP_NAME: string; ariaLabel: string; }
|
||||
>INVALID_PROP_NAME : string
|
||||
>'share' : "share"
|
||||
>ariaLabel : string
|
||||
>'test label' : "test label"
|
||||
|
||||
@@ -20,11 +20,9 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(49,35): error TS2322: Type
|
||||
Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'.
|
||||
tests/cases/compiler/excessPropertyCheckWithUnions.ts(50,35): error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'.
|
||||
Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'.
|
||||
tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
|
||||
Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type '{ kind: "A"; n: AN; }'.
|
||||
Types of property 'n' are incompatible.
|
||||
Type '{ a: string; b: string; }' is not assignable to type 'AN'.
|
||||
Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
|
||||
tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2326: Types of property 'n' are incompatible.
|
||||
Type '{ a: string; b: string; }' is not assignable to type 'AN'.
|
||||
Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (10 errors) ====
|
||||
@@ -127,11 +125,9 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type
|
||||
a: "a",
|
||||
b: "b", // excess -- kind: "A"
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
|
||||
!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type '{ kind: "A"; n: AN; }'.
|
||||
!!! error TS2322: Types of property 'n' are incompatible.
|
||||
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'AN'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
|
||||
!!! error TS2326: Types of property 'n' are incompatible.
|
||||
!!! error TS2326: Type '{ a: string; b: string; }' is not assignable to type 'AN'.
|
||||
!!! error TS2326: Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
|
||||
}
|
||||
}
|
||||
const abac: AB = {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(18,19): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(19,31): error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type 'A'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(22,19): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(23,31): error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type 'A'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(34,5): error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'.
|
||||
Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(43,9): error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'.
|
||||
Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(68,32): error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'View<TypeA>'.
|
||||
Object literal may only specify known properties, and 'boo' does not exist in type 'View<TypeA>'.
|
||||
tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts(70,50): error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'boolean | View<TypeB>'.
|
||||
Object literal may only specify known properties, and 'boo' does not exist in type 'View<TypeB>'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts (8 errors) ====
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
|
||||
interface A {
|
||||
x: string
|
||||
}
|
||||
|
||||
interface B {
|
||||
a: A;
|
||||
}
|
||||
|
||||
interface C {
|
||||
c: number;
|
||||
}
|
||||
|
||||
type D = B & C;
|
||||
|
||||
let a: B = { a: { x: 'hello' } }; // ok
|
||||
let b: B = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:4:5: The expected type comes from property 'x' which is declared here on type 'A'
|
||||
let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
~~~~
|
||||
!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type 'A'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:8:5: The expected type comes from property 'a' which is declared here on type 'B'
|
||||
|
||||
let d: D = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:4:5: The expected type comes from property 'x' which is declared here on type 'A'
|
||||
let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
~~~~
|
||||
!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'A'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type 'A'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:8:5: The expected type comes from property 'a' which is declared here on type 'D'
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/18075
|
||||
|
||||
export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } }
|
||||
|
||||
export let obj: MyType;
|
||||
|
||||
export const photo: typeof obj.photo = {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 1 // Great! This causes an error!
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'.
|
||||
};
|
||||
|
||||
export const myInstance: MyType = {
|
||||
id: 1,
|
||||
name: '',
|
||||
photo: {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 2 // This should also be an error
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '{ id: number; url: string; xyz: number; }' is not assignable to type '{ id: number; } & { url: string; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'xyz' does not exist in type '{ id: number; } & { url: string; }'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:27:62: The expected type comes from property 'photo' which is declared here on type 'MyType'
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/28616
|
||||
|
||||
export type View<T> = { [K in keyof T]: T[K] extends object ? boolean | View<T[K]> : boolean };
|
||||
|
||||
interface TypeC {
|
||||
foo: string;
|
||||
bar: string;
|
||||
}
|
||||
|
||||
interface TypeB {
|
||||
foo: string,
|
||||
bar: TypeC
|
||||
}
|
||||
|
||||
interface TypeA {
|
||||
foo: string,
|
||||
bar: TypeB,
|
||||
}
|
||||
|
||||
let test: View<TypeA>;
|
||||
|
||||
test = { foo: true, bar: true, boo: true }
|
||||
~~~~~~~~~
|
||||
!!! error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'View<TypeA>'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'boo' does not exist in type 'View<TypeA>'.
|
||||
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } }
|
||||
~~~~~~~~~
|
||||
!!! error TS2322: Type '{ foo: true; bar: true; boo: boolean; }' is not assignable to type 'boolean | View<TypeB>'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'boo' does not exist in type 'View<TypeB>'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts:63:5: The expected type comes from property 'bar' which is declared here on type 'View<TypeA>'
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
//// [excessPropertyChecksWithNestedIntersections.ts]
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
|
||||
interface A {
|
||||
x: string
|
||||
}
|
||||
|
||||
interface B {
|
||||
a: A;
|
||||
}
|
||||
|
||||
interface C {
|
||||
c: number;
|
||||
}
|
||||
|
||||
type D = B & C;
|
||||
|
||||
let a: B = { a: { x: 'hello' } }; // ok
|
||||
let b: B = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
|
||||
let d: D = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/18075
|
||||
|
||||
export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } }
|
||||
|
||||
export let obj: MyType;
|
||||
|
||||
export const photo: typeof obj.photo = {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 1 // Great! This causes an error!
|
||||
};
|
||||
|
||||
export const myInstance: MyType = {
|
||||
id: 1,
|
||||
name: '',
|
||||
photo: {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 2 // This should also be an error
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/28616
|
||||
|
||||
export type View<T> = { [K in keyof T]: T[K] extends object ? boolean | View<T[K]> : boolean };
|
||||
|
||||
interface TypeC {
|
||||
foo: string;
|
||||
bar: string;
|
||||
}
|
||||
|
||||
interface TypeB {
|
||||
foo: string,
|
||||
bar: TypeC
|
||||
}
|
||||
|
||||
interface TypeA {
|
||||
foo: string,
|
||||
bar: TypeB,
|
||||
}
|
||||
|
||||
let test: View<TypeA>;
|
||||
|
||||
test = { foo: true, bar: true, boo: true }
|
||||
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } }
|
||||
|
||||
|
||||
//// [excessPropertyChecksWithNestedIntersections.js]
|
||||
"use strict";
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
exports.__esModule = true;
|
||||
var a = { a: { x: 'hello' } }; // ok
|
||||
var b = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
var c = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
var d = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
var e = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
var f = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
exports.photo = {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 1 // Great! This causes an error!
|
||||
};
|
||||
exports.myInstance = {
|
||||
id: 1,
|
||||
name: '',
|
||||
photo: {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 2 // This should also be an error
|
||||
}
|
||||
};
|
||||
var test;
|
||||
test = { foo: true, bar: true, boo: true };
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } };
|
||||
@@ -0,0 +1,190 @@
|
||||
=== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(excessPropertyChecksWithNestedIntersections.ts, 0, 0))
|
||||
|
||||
x: string
|
||||
>x : Symbol(A.x, Decl(excessPropertyChecksWithNestedIntersections.ts, 2, 13))
|
||||
}
|
||||
|
||||
interface B {
|
||||
>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1))
|
||||
|
||||
a: A;
|
||||
>a : Symbol(B.a, Decl(excessPropertyChecksWithNestedIntersections.ts, 6, 13))
|
||||
>A : Symbol(A, Decl(excessPropertyChecksWithNestedIntersections.ts, 0, 0))
|
||||
}
|
||||
|
||||
interface C {
|
||||
>C : Symbol(C, Decl(excessPropertyChecksWithNestedIntersections.ts, 8, 1))
|
||||
|
||||
c: number;
|
||||
>c : Symbol(C.c, Decl(excessPropertyChecksWithNestedIntersections.ts, 10, 13))
|
||||
}
|
||||
|
||||
type D = B & C;
|
||||
>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1))
|
||||
>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1))
|
||||
>C : Symbol(C, Decl(excessPropertyChecksWithNestedIntersections.ts, 8, 1))
|
||||
|
||||
let a: B = { a: { x: 'hello' } }; // ok
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 3))
|
||||
>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 16, 17))
|
||||
|
||||
let b: B = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
>b : Symbol(b, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 3))
|
||||
>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 17, 17))
|
||||
|
||||
let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 3))
|
||||
>B : Symbol(B, Decl(excessPropertyChecksWithNestedIntersections.ts, 4, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 17))
|
||||
>y : Symbol(y, Decl(excessPropertyChecksWithNestedIntersections.ts, 18, 29))
|
||||
|
||||
let d: D = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
>d : Symbol(d, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 3))
|
||||
>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 17))
|
||||
>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 20, 31))
|
||||
|
||||
let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
>e : Symbol(e, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 3))
|
||||
>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 17))
|
||||
>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 21, 25))
|
||||
|
||||
let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
>f : Symbol(f, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 3))
|
||||
>D : Symbol(D, Decl(excessPropertyChecksWithNestedIntersections.ts, 12, 1))
|
||||
>a : Symbol(a, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 12))
|
||||
>x : Symbol(x, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 17))
|
||||
>y : Symbol(y, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 29))
|
||||
>c : Symbol(c, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 37))
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/18075
|
||||
|
||||
export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } }
|
||||
>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45))
|
||||
>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 22))
|
||||
>name : Symbol(name, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 40))
|
||||
>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60))
|
||||
>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 69))
|
||||
>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 87))
|
||||
|
||||
export let obj: MyType;
|
||||
>obj : Symbol(obj, Decl(excessPropertyChecksWithNestedIntersections.ts, 28, 10))
|
||||
>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45))
|
||||
|
||||
export const photo: typeof obj.photo = {
|
||||
>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 30, 12))
|
||||
>obj.photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60))
|
||||
>obj : Symbol(obj, Decl(excessPropertyChecksWithNestedIntersections.ts, 28, 10))
|
||||
>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 26, 60))
|
||||
|
||||
id: 1,
|
||||
>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 30, 40))
|
||||
|
||||
url: '',
|
||||
>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 31, 10))
|
||||
|
||||
xyz: 1 // Great! This causes an error!
|
||||
>xyz : Symbol(xyz, Decl(excessPropertyChecksWithNestedIntersections.ts, 32, 12))
|
||||
|
||||
};
|
||||
|
||||
export const myInstance: MyType = {
|
||||
>myInstance : Symbol(myInstance, Decl(excessPropertyChecksWithNestedIntersections.ts, 36, 12))
|
||||
>MyType : Symbol(MyType, Decl(excessPropertyChecksWithNestedIntersections.ts, 22, 45))
|
||||
|
||||
id: 1,
|
||||
>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 36, 35))
|
||||
|
||||
name: '',
|
||||
>name : Symbol(name, Decl(excessPropertyChecksWithNestedIntersections.ts, 37, 10))
|
||||
|
||||
photo: {
|
||||
>photo : Symbol(photo, Decl(excessPropertyChecksWithNestedIntersections.ts, 38, 13))
|
||||
|
||||
id: 1,
|
||||
>id : Symbol(id, Decl(excessPropertyChecksWithNestedIntersections.ts, 39, 12))
|
||||
|
||||
url: '',
|
||||
>url : Symbol(url, Decl(excessPropertyChecksWithNestedIntersections.ts, 40, 14))
|
||||
|
||||
xyz: 2 // This should also be an error
|
||||
>xyz : Symbol(xyz, Decl(excessPropertyChecksWithNestedIntersections.ts, 41, 16))
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/28616
|
||||
|
||||
export type View<T> = { [K in keyof T]: T[K] extends object ? boolean | View<T[K]> : boolean };
|
||||
>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2))
|
||||
>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17))
|
||||
>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25))
|
||||
>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17))
|
||||
>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17))
|
||||
>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25))
|
||||
>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2))
|
||||
>T : Symbol(T, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 17))
|
||||
>K : Symbol(K, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 25))
|
||||
|
||||
interface TypeC {
|
||||
>TypeC : Symbol(TypeC, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 95))
|
||||
|
||||
foo: string;
|
||||
>foo : Symbol(TypeC.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 50, 17))
|
||||
|
||||
bar: string;
|
||||
>bar : Symbol(TypeC.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 51, 16))
|
||||
}
|
||||
|
||||
interface TypeB {
|
||||
>TypeB : Symbol(TypeB, Decl(excessPropertyChecksWithNestedIntersections.ts, 53, 1))
|
||||
|
||||
foo: string,
|
||||
>foo : Symbol(TypeB.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 55, 17))
|
||||
|
||||
bar: TypeC
|
||||
>bar : Symbol(TypeB.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 56, 16))
|
||||
>TypeC : Symbol(TypeC, Decl(excessPropertyChecksWithNestedIntersections.ts, 48, 95))
|
||||
}
|
||||
|
||||
interface TypeA {
|
||||
>TypeA : Symbol(TypeA, Decl(excessPropertyChecksWithNestedIntersections.ts, 58, 1))
|
||||
|
||||
foo: string,
|
||||
>foo : Symbol(TypeA.foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 60, 17))
|
||||
|
||||
bar: TypeB,
|
||||
>bar : Symbol(TypeA.bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 61, 16))
|
||||
>TypeB : Symbol(TypeB, Decl(excessPropertyChecksWithNestedIntersections.ts, 53, 1))
|
||||
}
|
||||
|
||||
let test: View<TypeA>;
|
||||
>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3))
|
||||
>View : Symbol(View, Decl(excessPropertyChecksWithNestedIntersections.ts, 44, 2))
|
||||
>TypeA : Symbol(TypeA, Decl(excessPropertyChecksWithNestedIntersections.ts, 58, 1))
|
||||
|
||||
test = { foo: true, bar: true, boo: true }
|
||||
>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3))
|
||||
>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 8))
|
||||
>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 19))
|
||||
>boo : Symbol(boo, Decl(excessPropertyChecksWithNestedIntersections.ts, 67, 30))
|
||||
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } }
|
||||
>test : Symbol(test, Decl(excessPropertyChecksWithNestedIntersections.ts, 65, 3))
|
||||
>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 8))
|
||||
>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 19))
|
||||
>foo : Symbol(foo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 26))
|
||||
>bar : Symbol(bar, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 37))
|
||||
>boo : Symbol(boo, Decl(excessPropertyChecksWithNestedIntersections.ts, 69, 48))
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
=== tests/cases/compiler/excessPropertyChecksWithNestedIntersections.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
|
||||
interface A {
|
||||
x: string
|
||||
>x : string
|
||||
}
|
||||
|
||||
interface B {
|
||||
a: A;
|
||||
>a : A
|
||||
}
|
||||
|
||||
interface C {
|
||||
c: number;
|
||||
>c : number
|
||||
}
|
||||
|
||||
type D = B & C;
|
||||
>D : D
|
||||
|
||||
let a: B = { a: { x: 'hello' } }; // ok
|
||||
>a : B
|
||||
>{ a: { x: 'hello' } } : { a: { x: string; }; }
|
||||
>a : { x: string; }
|
||||
>{ x: 'hello' } : { x: string; }
|
||||
>x : string
|
||||
>'hello' : "hello"
|
||||
|
||||
let b: B = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
>b : B
|
||||
>{ a: { x: 2 } } : { a: { x: number; }; }
|
||||
>a : { x: number; }
|
||||
>{ x: 2 } : { x: number; }
|
||||
>x : number
|
||||
>2 : 2
|
||||
|
||||
let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
>c : B
|
||||
>{ a: { x: 'hello', y: 2 } } : { a: { x: string; y: number; }; }
|
||||
>a : { x: string; y: number; }
|
||||
>{ x: 'hello', y: 2 } : { x: string; y: number; }
|
||||
>x : string
|
||||
>'hello' : "hello"
|
||||
>y : number
|
||||
>2 : 2
|
||||
|
||||
let d: D = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
>d : D
|
||||
>{ a: { x: 'hello' }, c: 5 } : { a: { x: string; }; c: number; }
|
||||
>a : { x: string; }
|
||||
>{ x: 'hello' } : { x: string; }
|
||||
>x : string
|
||||
>'hello' : "hello"
|
||||
>c : number
|
||||
>5 : 5
|
||||
|
||||
let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
>e : D
|
||||
>{ a: { x: 2 }, c: 5 } : { a: { x: number; }; c: number; }
|
||||
>a : { x: number; }
|
||||
>{ x: 2 } : { x: number; }
|
||||
>x : number
|
||||
>2 : 2
|
||||
>c : number
|
||||
>5 : 5
|
||||
|
||||
let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
>f : D
|
||||
>{ a: { x: 'hello', y: 2 }, c: 5 } : { a: { x: string; y: number; }; c: number; }
|
||||
>a : { x: string; y: number; }
|
||||
>{ x: 'hello', y: 2 } : { x: string; y: number; }
|
||||
>x : string
|
||||
>'hello' : "hello"
|
||||
>y : number
|
||||
>2 : 2
|
||||
>c : number
|
||||
>5 : 5
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/18075
|
||||
|
||||
export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } }
|
||||
>MyType : MyType
|
||||
>id : number
|
||||
>name : string
|
||||
>photo : { id: number; } & { url: string; }
|
||||
>id : number
|
||||
>url : string
|
||||
|
||||
export let obj: MyType;
|
||||
>obj : MyType
|
||||
|
||||
export const photo: typeof obj.photo = {
|
||||
>photo : { id: number; } & { url: string; }
|
||||
>obj.photo : { id: number; } & { url: string; }
|
||||
>obj : MyType
|
||||
>photo : { id: number; } & { url: string; }
|
||||
>{ id: 1, url: '', xyz: 1 // Great! This causes an error!} : { id: number; url: string; xyz: number; }
|
||||
|
||||
id: 1,
|
||||
>id : number
|
||||
>1 : 1
|
||||
|
||||
url: '',
|
||||
>url : string
|
||||
>'' : ""
|
||||
|
||||
xyz: 1 // Great! This causes an error!
|
||||
>xyz : number
|
||||
>1 : 1
|
||||
|
||||
};
|
||||
|
||||
export const myInstance: MyType = {
|
||||
>myInstance : MyType
|
||||
>{ id: 1, name: '', photo: { id: 1, url: '', xyz: 2 // This should also be an error }} : { id: number; name: string; photo: { id: number; url: string; xyz: number; }; }
|
||||
|
||||
id: 1,
|
||||
>id : number
|
||||
>1 : 1
|
||||
|
||||
name: '',
|
||||
>name : string
|
||||
>'' : ""
|
||||
|
||||
photo: {
|
||||
>photo : { id: number; url: string; xyz: number; }
|
||||
>{ id: 1, url: '', xyz: 2 // This should also be an error } : { id: number; url: string; xyz: number; }
|
||||
|
||||
id: 1,
|
||||
>id : number
|
||||
>1 : 1
|
||||
|
||||
url: '',
|
||||
>url : string
|
||||
>'' : ""
|
||||
|
||||
xyz: 2 // This should also be an error
|
||||
>xyz : number
|
||||
>2 : 2
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/28616
|
||||
|
||||
export type View<T> = { [K in keyof T]: T[K] extends object ? boolean | View<T[K]> : boolean };
|
||||
>View : View<T>
|
||||
|
||||
interface TypeC {
|
||||
foo: string;
|
||||
>foo : string
|
||||
|
||||
bar: string;
|
||||
>bar : string
|
||||
}
|
||||
|
||||
interface TypeB {
|
||||
foo: string,
|
||||
>foo : string
|
||||
|
||||
bar: TypeC
|
||||
>bar : TypeC
|
||||
}
|
||||
|
||||
interface TypeA {
|
||||
foo: string,
|
||||
>foo : string
|
||||
|
||||
bar: TypeB,
|
||||
>bar : TypeB
|
||||
}
|
||||
|
||||
let test: View<TypeA>;
|
||||
>test : View<TypeA>
|
||||
|
||||
test = { foo: true, bar: true, boo: true }
|
||||
>test = { foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; }
|
||||
>test : View<TypeA>
|
||||
>{ foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; }
|
||||
>foo : true
|
||||
>true : true
|
||||
>bar : true
|
||||
>true : true
|
||||
>boo : boolean
|
||||
>true : true
|
||||
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } }
|
||||
>test = { foo: true, bar: { foo: true, bar: true, boo: true } } : { foo: true; bar: { foo: true; bar: true; boo: boolean; }; }
|
||||
>test : View<TypeA>
|
||||
>{ foo: true, bar: { foo: true, bar: true, boo: true } } : { foo: true; bar: { foo: true; bar: true; boo: boolean; }; }
|
||||
>foo : true
|
||||
>true : true
|
||||
>bar : { foo: true; bar: true; boo: boolean; }
|
||||
>{ foo: true, bar: true, boo: true } : { foo: true; bar: true; boo: boolean; }
|
||||
>foo : true
|
||||
>true : true
|
||||
>bar : true
|
||||
>true : true
|
||||
>boo : boolean
|
||||
>true : true
|
||||
|
||||
@@ -2,7 +2,21 @@
|
||||
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
|
||||
declare const a: { [index: string]: number };
|
||||
fn(a);
|
||||
|
||||
// Repro from #30218
|
||||
|
||||
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
|
||||
|
||||
enum E { A = 'foo', B = 'bar' }
|
||||
|
||||
let x: E[] = enumValues(E);
|
||||
|
||||
|
||||
//// [mappedToToIndexSignatureInference.js]
|
||||
fn(a);
|
||||
var E;
|
||||
(function (E) {
|
||||
E["A"] = "foo";
|
||||
E["B"] = "bar";
|
||||
})(E || (E = {}));
|
||||
var x = enumValues(E);
|
||||
|
||||
@@ -16,3 +16,26 @@ fn(a);
|
||||
>fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13))
|
||||
|
||||
// Repro from #30218
|
||||
|
||||
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
|
||||
>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6))
|
||||
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28))
|
||||
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
|
||||
>e : Symbol(e, Decl(mappedToToIndexSignatureInference.ts, 6, 64))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28))
|
||||
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
|
||||
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
|
||||
|
||||
enum E { A = 'foo', B = 'bar' }
|
||||
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
|
||||
>A : Symbol(E.A, Decl(mappedToToIndexSignatureInference.ts, 8, 8))
|
||||
>B : Symbol(E.B, Decl(mappedToToIndexSignatureInference.ts, 8, 19))
|
||||
|
||||
let x: E[] = enumValues(E);
|
||||
>x : Symbol(x, Decl(mappedToToIndexSignatureInference.ts, 10, 3))
|
||||
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
|
||||
>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6))
|
||||
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
|
||||
|
||||
|
||||
@@ -12,3 +12,22 @@ fn(a);
|
||||
>fn : <K extends string, V>(object: { [Key in K]: V; }) => object
|
||||
>a : { [index: string]: number; }
|
||||
|
||||
// Repro from #30218
|
||||
|
||||
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
|
||||
>enumValues : <K extends string, V extends string>(e: Record<K, V>) => V[]
|
||||
>e : Record<K, V>
|
||||
|
||||
enum E { A = 'foo', B = 'bar' }
|
||||
>E : E
|
||||
>A : E.A
|
||||
>'foo' : "foo"
|
||||
>B : E.B
|
||||
>'bar' : "bar"
|
||||
|
||||
let x: E[] = enumValues(E);
|
||||
>x : E[]
|
||||
>enumValues(E) : E[]
|
||||
>enumValues : <K extends string, V extends string>(e: Record<K, V>) => V[]
|
||||
>E : typeof E
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(13,35): error TS2322: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'number | IProps'.
|
||||
Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'.
|
||||
tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(16,7): error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'number | IProps'.
|
||||
Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'IProps'.
|
||||
Types of property 'nestedProp' are incompatible.
|
||||
Type '{ asdfasdf: string; }' has no properties in common with type '{ testBool?: boolean; }'.
|
||||
tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts(19,56): error TS2326: Types of property 'nestedProps' are incompatible.
|
||||
Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'IProps'.
|
||||
Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts (3 errors) ====
|
||||
interface IProps {
|
||||
iconProp?: string;
|
||||
nestedProp?: {
|
||||
testBool?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface INestedProps {
|
||||
nestedProps?: IProps;
|
||||
}
|
||||
|
||||
// These are the types of errors we want:
|
||||
const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'number | IProps'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'.
|
||||
|
||||
// Nested typing works here and we also get an expected error:
|
||||
const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'number | IProps'.
|
||||
!!! error TS2322: Type '{ nestedProp: { asdfasdf: string; }; iconProp: string; }' is not assignable to type 'IProps'.
|
||||
!!! error TS2322: Types of property 'nestedProp' are incompatible.
|
||||
!!! error TS2322: Type '{ asdfasdf: string; }' has no properties in common with type '{ testBool?: boolean; }'.
|
||||
|
||||
// Want an error generated here but there isn't one.
|
||||
const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2326: Types of property 'nestedProps' are incompatible.
|
||||
!!! error TS2326: Type '{ INVALID_PROP_NAME: string; iconProp: string; }' is not assignable to type 'IProps'.
|
||||
!!! error TS2326: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'IProps'.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//// [nonObjectUnionNestedExcessPropertyCheck.ts]
|
||||
interface IProps {
|
||||
iconProp?: string;
|
||||
nestedProp?: {
|
||||
testBool?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface INestedProps {
|
||||
nestedProps?: IProps;
|
||||
}
|
||||
|
||||
// These are the types of errors we want:
|
||||
const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
|
||||
// Nested typing works here and we also get an expected error:
|
||||
const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
|
||||
// Want an error generated here but there isn't one.
|
||||
const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
|
||||
|
||||
//// [nonObjectUnionNestedExcessPropertyCheck.js]
|
||||
// These are the types of errors we want:
|
||||
var propB1 = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
// Nested typing works here and we also get an expected error:
|
||||
var propB2 = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
// Want an error generated here but there isn't one.
|
||||
var propA1 = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
@@ -0,0 +1,46 @@
|
||||
=== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts ===
|
||||
interface IProps {
|
||||
>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0))
|
||||
|
||||
iconProp?: string;
|
||||
>iconProp : Symbol(IProps.iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 18))
|
||||
|
||||
nestedProp?: {
|
||||
>nestedProp : Symbol(IProps.nestedProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 1, 22))
|
||||
|
||||
testBool?: boolean;
|
||||
>testBool : Symbol(testBool, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 2, 18))
|
||||
}
|
||||
}
|
||||
|
||||
interface INestedProps {
|
||||
>INestedProps : Symbol(INestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 5, 1))
|
||||
|
||||
nestedProps?: IProps;
|
||||
>nestedProps : Symbol(INestedProps.nestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 7, 24))
|
||||
>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0))
|
||||
}
|
||||
|
||||
// These are the types of errors we want:
|
||||
const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
>propB1 : Symbol(propB1, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 5))
|
||||
>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0))
|
||||
>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 33))
|
||||
>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 12, 61))
|
||||
|
||||
// Nested typing works here and we also get an expected error:
|
||||
const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
>propB2 : Symbol(propB2, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 5))
|
||||
>IProps : Symbol(IProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 0, 0))
|
||||
>nestedProp : Symbol(nestedProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 33))
|
||||
>asdfasdf : Symbol(asdfasdf, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 47))
|
||||
>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 15, 67))
|
||||
|
||||
// Want an error generated here but there isn't one.
|
||||
const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
>propA1 : Symbol(propA1, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 5))
|
||||
>INestedProps : Symbol(INestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 5, 1))
|
||||
>nestedProps : Symbol(nestedProps, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 39))
|
||||
>INVALID_PROP_NAME : Symbol(INVALID_PROP_NAME, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 54))
|
||||
>iconProp : Symbol(iconProp, Decl(nonObjectUnionNestedExcessPropertyCheck.ts, 18, 82))
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
=== tests/cases/compiler/nonObjectUnionNestedExcessPropertyCheck.ts ===
|
||||
interface IProps {
|
||||
iconProp?: string;
|
||||
>iconProp : string
|
||||
|
||||
nestedProp?: {
|
||||
>nestedProp : { testBool?: boolean; }
|
||||
|
||||
testBool?: boolean;
|
||||
>testBool : boolean
|
||||
}
|
||||
}
|
||||
|
||||
interface INestedProps {
|
||||
nestedProps?: IProps;
|
||||
>nestedProps : IProps
|
||||
}
|
||||
|
||||
// These are the types of errors we want:
|
||||
const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
>propB1 : number | IProps
|
||||
>{ INVALID_PROP_NAME: 'share', iconProp: 'test' } : { INVALID_PROP_NAME: string; iconProp: string; }
|
||||
>INVALID_PROP_NAME : string
|
||||
>'share' : "share"
|
||||
>iconProp : string
|
||||
>'test' : "test"
|
||||
|
||||
// Nested typing works here and we also get an expected error:
|
||||
const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
>propB2 : number | IProps
|
||||
>{ nestedProp: { asdfasdf: 'test' }, iconProp: 'test' } : { nestedProp: { asdfasdf: string; }; iconProp: string; }
|
||||
>nestedProp : { asdfasdf: string; }
|
||||
>{ asdfasdf: 'test' } : { asdfasdf: string; }
|
||||
>asdfasdf : string
|
||||
>'test' : "test"
|
||||
>iconProp : string
|
||||
>'test' : "test"
|
||||
|
||||
// Want an error generated here but there isn't one.
|
||||
const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
>propA1 : number | INestedProps
|
||||
>{ nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } } : { nestedProps: { INVALID_PROP_NAME: string; iconProp: string; }; }
|
||||
>nestedProps : { INVALID_PROP_NAME: string; iconProp: string; }
|
||||
>{ INVALID_PROP_NAME: 'share', iconProp: 'test' } : { INVALID_PROP_NAME: string; iconProp: string; }
|
||||
>INVALID_PROP_NAME : string
|
||||
>'share' : "share"
|
||||
>iconProp : string
|
||||
>'test' : "test"
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
//// [/src/core/anotherModule.d.ts]
|
||||
export declare const World = "hello";
|
||||
|
||||
|
||||
//// [/src/core/index.d.ts]
|
||||
export declare const someString: string;
|
||||
export declare function leftPad(s: string, n: number): string;
|
||||
export declare function multiply(a: number, b: number): number;
|
||||
|
||||
|
||||
//// [/src/core/tsconfig.json]
|
||||
{
|
||||
"compilerOptions": {
|
||||
"incremental": true, "declaration": true,
|
||||
"skipDefaultLibCheck": true
|
||||
}
|
||||
}
|
||||
|
||||
//// [/src/core/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"/lib/lib.d.ts": {
|
||||
"version": "/lib/lib.d.ts",
|
||||
"signature": "/lib/lib.d.ts"
|
||||
},
|
||||
"/lib/lib.es5.d.ts": {
|
||||
"version": "/lib/lib.es5.d.ts",
|
||||
"signature": "/lib/lib.es5.d.ts"
|
||||
},
|
||||
"/lib/lib.dom.d.ts": {
|
||||
"version": "/lib/lib.dom.d.ts",
|
||||
"signature": "/lib/lib.dom.d.ts"
|
||||
},
|
||||
"/lib/lib.webworker.importscripts.d.ts": {
|
||||
"version": "/lib/lib.webworker.importscripts.d.ts",
|
||||
"signature": "/lib/lib.webworker.importscripts.d.ts"
|
||||
},
|
||||
"/lib/lib.scripthost.d.ts": {
|
||||
"version": "/lib/lib.scripthost.d.ts",
|
||||
"signature": "/lib/lib.scripthost.d.ts"
|
||||
},
|
||||
"/src/core/anothermodule.ts": {
|
||||
"version": "-2676574883",
|
||||
"signature": "-8396256275"
|
||||
},
|
||||
"/src/core/index.ts": {
|
||||
"version": "-18749805970",
|
||||
"signature": "1874987148"
|
||||
},
|
||||
"/src/core/some_decl.d.ts": {
|
||||
"version": "-9253692965",
|
||||
"signature": "-9253692965"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"incremental": true,
|
||||
"declaration": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"configFilePath": "/src/core/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"/lib/lib.d.ts",
|
||||
"/lib/lib.dom.d.ts",
|
||||
"/lib/lib.es5.d.ts",
|
||||
"/lib/lib.scripthost.d.ts",
|
||||
"/lib/lib.webworker.importscripts.d.ts",
|
||||
"/src/core/anothermodule.ts",
|
||||
"/src/core/index.ts",
|
||||
"/src/core/some_decl.d.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
//// [/src/core/anotherModule.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.World = "hello";
|
||||
|
||||
|
||||
//// [/src/core/index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.someString = "HELLO WORLD";
|
||||
function leftPad(s, n) { return s + n; }
|
||||
exports.leftPad = leftPad;
|
||||
function multiply(a, b) { return a * b; }
|
||||
exports.multiply = multiply;
|
||||
|
||||
|
||||
//// [/src/core/tsconfig.json]
|
||||
{
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"skipDefaultLibCheck": true
|
||||
}
|
||||
}
|
||||
|
||||
//// [/src/core/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"/lib/lib.d.ts": {
|
||||
"version": "/lib/lib.d.ts",
|
||||
"signature": "/lib/lib.d.ts"
|
||||
},
|
||||
"/lib/lib.es5.d.ts": {
|
||||
"version": "/lib/lib.es5.d.ts",
|
||||
"signature": "/lib/lib.es5.d.ts"
|
||||
},
|
||||
"/lib/lib.dom.d.ts": {
|
||||
"version": "/lib/lib.dom.d.ts",
|
||||
"signature": "/lib/lib.dom.d.ts"
|
||||
},
|
||||
"/lib/lib.webworker.importscripts.d.ts": {
|
||||
"version": "/lib/lib.webworker.importscripts.d.ts",
|
||||
"signature": "/lib/lib.webworker.importscripts.d.ts"
|
||||
},
|
||||
"/lib/lib.scripthost.d.ts": {
|
||||
"version": "/lib/lib.scripthost.d.ts",
|
||||
"signature": "/lib/lib.scripthost.d.ts"
|
||||
},
|
||||
"/src/core/anothermodule.ts": {
|
||||
"version": "-2676574883",
|
||||
"signature": "-8396256275"
|
||||
},
|
||||
"/src/core/index.ts": {
|
||||
"version": "-18749805970",
|
||||
"signature": "1874987148"
|
||||
},
|
||||
"/src/core/some_decl.d.ts": {
|
||||
"version": "-9253692965",
|
||||
"signature": "-9253692965"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"incremental": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"configFilePath": "/src/core/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"/lib/lib.d.ts",
|
||||
"/lib/lib.dom.d.ts",
|
||||
"/lib/lib.es5.d.ts",
|
||||
"/lib/lib.scripthost.d.ts",
|
||||
"/lib/lib.webworker.importscripts.d.ts",
|
||||
"/src/core/anothermodule.ts",
|
||||
"/src/core/index.ts",
|
||||
"/src/core/some_decl.d.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts]
|
||||
interface IStringDictionary<V> {
|
||||
[name: string]: V;
|
||||
}
|
||||
interface INumberDictionary<V> {
|
||||
[idx: number]: V;
|
||||
}
|
||||
|
||||
declare function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any);
|
||||
|
||||
let count = 0;
|
||||
forEach({ toString: 123 }, () => count++);
|
||||
|
||||
|
||||
//// [unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.js]
|
||||
var count = 0;
|
||||
forEach({ toString: 123 }, function () { return count++; });
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
=== tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts ===
|
||||
interface IStringDictionary<V> {
|
||||
>IStringDictionary : Symbol(IStringDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 0))
|
||||
>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 28))
|
||||
|
||||
[name: string]: V;
|
||||
>name : Symbol(name, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 1, 2))
|
||||
>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 28))
|
||||
}
|
||||
interface INumberDictionary<V> {
|
||||
>INumberDictionary : Symbol(INumberDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 2, 1))
|
||||
>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 3, 28))
|
||||
|
||||
[idx: number]: V;
|
||||
>idx : Symbol(idx, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 4, 2))
|
||||
>V : Symbol(V, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 3, 28))
|
||||
}
|
||||
|
||||
declare function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any);
|
||||
>forEach : Symbol(forEach, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 5, 1))
|
||||
>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25))
|
||||
>from : Symbol(from, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 28))
|
||||
>IStringDictionary : Symbol(IStringDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25))
|
||||
>INumberDictionary : Symbol(INumberDictionary, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 2, 1))
|
||||
>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25))
|
||||
>callback : Symbol(callback, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 78))
|
||||
>entry : Symbol(entry, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 90))
|
||||
>key : Symbol(key, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 98))
|
||||
>value : Symbol(value, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 108))
|
||||
>T : Symbol(T, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 25))
|
||||
>remove : Symbol(remove, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 7, 121))
|
||||
|
||||
let count = 0;
|
||||
>count : Symbol(count, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 9, 3))
|
||||
|
||||
forEach({ toString: 123 }, () => count++);
|
||||
>forEach : Symbol(forEach, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 5, 1))
|
||||
>toString : Symbol(toString, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 10, 9))
|
||||
>count : Symbol(count, Decl(unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts, 9, 3))
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/unionExcessPropertyCheckNoApparentPropTypeMismatchErrors.ts ===
|
||||
interface IStringDictionary<V> {
|
||||
[name: string]: V;
|
||||
>name : string
|
||||
}
|
||||
interface INumberDictionary<V> {
|
||||
[idx: number]: V;
|
||||
>idx : number
|
||||
}
|
||||
|
||||
declare function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any);
|
||||
>forEach : <T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any) => any
|
||||
>from : IStringDictionary<T> | INumberDictionary<T>
|
||||
>callback : (entry: { key: any; value: T; }, remove: () => void) => any
|
||||
>entry : { key: any; value: T; }
|
||||
>key : any
|
||||
>value : T
|
||||
>remove : () => void
|
||||
|
||||
let count = 0;
|
||||
>count : number
|
||||
>0 : 0
|
||||
|
||||
forEach({ toString: 123 }, () => count++);
|
||||
>forEach({ toString: 123 }, () => count++) : any
|
||||
>forEach : <T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any) => any
|
||||
>{ toString: 123 } : { toString: number; }
|
||||
>toString : number
|
||||
>123 : 123
|
||||
>() => count++ : () => number
|
||||
>count++ : number
|
||||
>count : number
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//// [unionExcessPropsWithPartialMember.ts]
|
||||
interface A {
|
||||
unused?: string;
|
||||
x: string;
|
||||
}
|
||||
|
||||
interface B {
|
||||
x: string;
|
||||
y: string;
|
||||
}
|
||||
|
||||
declare var ab: A | B;
|
||||
declare var a: A;
|
||||
|
||||
ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A`
|
||||
|
||||
|
||||
//// [unionExcessPropsWithPartialMember.js]
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
ab = __assign({}, a, { y: null }); // Should be allowed, since `y` is missing on `A`
|
||||
@@ -0,0 +1,35 @@
|
||||
=== tests/cases/compiler/unionExcessPropsWithPartialMember.ts ===
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0))
|
||||
|
||||
unused?: string;
|
||||
>unused : Symbol(A.unused, Decl(unionExcessPropsWithPartialMember.ts, 0, 13))
|
||||
|
||||
x: string;
|
||||
>x : Symbol(A.x, Decl(unionExcessPropsWithPartialMember.ts, 1, 20))
|
||||
}
|
||||
|
||||
interface B {
|
||||
>B : Symbol(B, Decl(unionExcessPropsWithPartialMember.ts, 3, 1))
|
||||
|
||||
x: string;
|
||||
>x : Symbol(B.x, Decl(unionExcessPropsWithPartialMember.ts, 5, 13))
|
||||
|
||||
y: string;
|
||||
>y : Symbol(B.y, Decl(unionExcessPropsWithPartialMember.ts, 6, 14))
|
||||
}
|
||||
|
||||
declare var ab: A | B;
|
||||
>ab : Symbol(ab, Decl(unionExcessPropsWithPartialMember.ts, 10, 11))
|
||||
>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(unionExcessPropsWithPartialMember.ts, 3, 1))
|
||||
|
||||
declare var a: A;
|
||||
>a : Symbol(a, Decl(unionExcessPropsWithPartialMember.ts, 11, 11))
|
||||
>A : Symbol(A, Decl(unionExcessPropsWithPartialMember.ts, 0, 0))
|
||||
|
||||
ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A`
|
||||
>ab : Symbol(ab, Decl(unionExcessPropsWithPartialMember.ts, 10, 11))
|
||||
>a : Symbol(a, Decl(unionExcessPropsWithPartialMember.ts, 11, 11))
|
||||
>y : Symbol(y, Decl(unionExcessPropsWithPartialMember.ts, 13, 11))
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/compiler/unionExcessPropsWithPartialMember.ts ===
|
||||
interface A {
|
||||
unused?: string;
|
||||
>unused : string | undefined
|
||||
|
||||
x: string;
|
||||
>x : string
|
||||
}
|
||||
|
||||
interface B {
|
||||
x: string;
|
||||
>x : string
|
||||
|
||||
y: string;
|
||||
>y : string
|
||||
}
|
||||
|
||||
declare var ab: A | B;
|
||||
>ab : A | B
|
||||
|
||||
declare var a: A;
|
||||
>a : A
|
||||
|
||||
ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A`
|
||||
>ab = {...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; }
|
||||
>ab : A | B
|
||||
>{...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; }
|
||||
>a : A
|
||||
>y : string | undefined
|
||||
>(null as any as string | undefined) : string | undefined
|
||||
>null as any as string | undefined : string | undefined
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
interface StatelessComponent<P = {}> {
|
||||
(props: P & { children?: number }, context?: any): null;
|
||||
}
|
||||
|
||||
const TestComponent: StatelessComponent<TestProps> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
interface ITestProps {
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
interface NestedProp<TProps> {
|
||||
props: TProps;
|
||||
}
|
||||
|
||||
interface TestProps {
|
||||
icon: NestedProp<ITestProps>;
|
||||
}
|
||||
|
||||
TestComponent({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
|
||||
const TestComponent2: StatelessComponent<TestProps | {props2: {x: number}}> = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }});
|
||||
@@ -0,0 +1,70 @@
|
||||
// https://github.com/Microsoft/TypeScript/issues/13813
|
||||
|
||||
interface A {
|
||||
x: string
|
||||
}
|
||||
|
||||
interface B {
|
||||
a: A;
|
||||
}
|
||||
|
||||
interface C {
|
||||
c: number;
|
||||
}
|
||||
|
||||
type D = B & C;
|
||||
|
||||
let a: B = { a: { x: 'hello' } }; // ok
|
||||
let b: B = { a: { x: 2 } }; // error - types of property x are incompatible
|
||||
let c: B = { a: { x: 'hello', y: 2 } }; // error - y does not exist in type A
|
||||
|
||||
let d: D = { a: { x: 'hello' }, c: 5 }; // ok
|
||||
let e: D = { a: { x: 2 }, c: 5 }; // error - types of property x are incompatible
|
||||
let f: D = { a: { x: 'hello', y: 2 }, c: 5 }; // should be an error
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/18075
|
||||
|
||||
export type MyType = { id: number; } & { name: string; } & { photo: { id: number; } & { url: string; } }
|
||||
|
||||
export let obj: MyType;
|
||||
|
||||
export const photo: typeof obj.photo = {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 1 // Great! This causes an error!
|
||||
};
|
||||
|
||||
export const myInstance: MyType = {
|
||||
id: 1,
|
||||
name: '',
|
||||
photo: {
|
||||
id: 1,
|
||||
url: '',
|
||||
xyz: 2 // This should also be an error
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/28616
|
||||
|
||||
export type View<T> = { [K in keyof T]: T[K] extends object ? boolean | View<T[K]> : boolean };
|
||||
|
||||
interface TypeC {
|
||||
foo: string;
|
||||
bar: string;
|
||||
}
|
||||
|
||||
interface TypeB {
|
||||
foo: string,
|
||||
bar: TypeC
|
||||
}
|
||||
|
||||
interface TypeA {
|
||||
foo: string,
|
||||
bar: TypeB,
|
||||
}
|
||||
|
||||
let test: View<TypeA>;
|
||||
|
||||
test = { foo: true, bar: true, boo: true }
|
||||
|
||||
test = { foo: true, bar: { foo: true, bar: true, boo: true } }
|
||||
@@ -1,3 +1,11 @@
|
||||
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
|
||||
declare const a: { [index: string]: number };
|
||||
fn(a);
|
||||
|
||||
// Repro from #30218
|
||||
|
||||
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
|
||||
|
||||
enum E { A = 'foo', B = 'bar' }
|
||||
|
||||
let x: E[] = enumValues(E);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
interface IProps {
|
||||
iconProp?: string;
|
||||
nestedProp?: {
|
||||
testBool?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface INestedProps {
|
||||
nestedProps?: IProps;
|
||||
}
|
||||
|
||||
// These are the types of errors we want:
|
||||
const propB1: IProps | number = { INVALID_PROP_NAME: 'share', iconProp: 'test' };
|
||||
|
||||
// Nested typing works here and we also get an expected error:
|
||||
const propB2: IProps | number = { nestedProp: { asdfasdf: 'test' }, iconProp: 'test' };
|
||||
|
||||
// Want an error generated here but there isn't one.
|
||||
const propA1: INestedProps | number = { nestedProps: { INVALID_PROP_NAME: 'share', iconProp: 'test' } };
|
||||
@@ -0,0 +1,11 @@
|
||||
interface IStringDictionary<V> {
|
||||
[name: string]: V;
|
||||
}
|
||||
interface INumberDictionary<V> {
|
||||
[idx: number]: V;
|
||||
}
|
||||
|
||||
declare function forEach<T>(from: IStringDictionary<T> | INumberDictionary<T>, callback: (entry: { key: any; value: T; }, remove: () => void) => any);
|
||||
|
||||
let count = 0;
|
||||
forEach({ toString: 123 }, () => count++);
|
||||
@@ -0,0 +1,15 @@
|
||||
// @strict: true
|
||||
interface A {
|
||||
unused?: string;
|
||||
x: string;
|
||||
}
|
||||
|
||||
interface B {
|
||||
x: string;
|
||||
y: string;
|
||||
}
|
||||
|
||||
declare var ab: A | B;
|
||||
declare var a: A;
|
||||
|
||||
ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A`
|
||||
Reference in New Issue
Block a user