Merge branch 'master' into interfaceFixes

This commit is contained in:
Arthur Ozga
2016-12-05 13:49:23 -08:00
111 changed files with 7434 additions and 819 deletions
-23
View File
@@ -518,7 +518,6 @@ namespace ts {
hasExplicitReturn = false;
bindChildren(node);
// Reset all reachability check related flags on node (for incremental scenarios)
// Reset all emit helper flags on node (for incremental scenarios)
node.flags &= ~NodeFlags.ReachabilityAndEmitFlags;
if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
node.flags |= NodeFlags.HasImplicitReturn;
@@ -1950,9 +1949,6 @@ namespace ts {
return bindParameter(<ParameterDeclaration>node);
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
if ((node as BindingElement).dotDotDotToken && node.parent.kind === SyntaxKind.ObjectBindingPattern) {
emitFlags |= NodeFlags.HasRestAttribute;
}
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
@@ -1980,7 +1976,6 @@ namespace ts {
}
root = root.parent;
}
emitFlags |= hasRest ? NodeFlags.HasRestAttribute : NodeFlags.HasSpreadAttribute;
return;
case SyntaxKind.CallSignature:
@@ -2236,15 +2231,6 @@ namespace ts {
}
function bindClassLikeDeclaration(node: ClassLikeDeclaration) {
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
if (getClassExtendsHeritageClauseElement(node) !== undefined) {
emitFlags |= NodeFlags.HasClassExtends;
}
if (nodeIsDecorated(node)) {
emitFlags |= NodeFlags.HasDecorators;
}
}
if (node.kind === SyntaxKind.ClassDeclaration) {
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
}
@@ -2314,12 +2300,6 @@ namespace ts {
}
function bindParameter(node: ParameterDeclaration) {
if (!isDeclarationFile(file) &&
!isInAmbientContext(node) &&
nodeIsDecorated(node)) {
emitFlags |= (NodeFlags.HasDecorators | NodeFlags.HasParamDecorators);
}
if (inStrictMode) {
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
@@ -2377,9 +2357,6 @@ namespace ts {
if (isAsyncFunctionLike(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
if (nodeIsDecorated(node)) {
emitFlags |= NodeFlags.HasDecorators;
}
}
if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) {
+275 -154
View File
@@ -38,6 +38,8 @@ namespace ts {
// is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
// they no longer need the information (for example, if the user started editing again).
let cancellationToken: CancellationToken;
let requestedExternalEmitHelpers: ExternalEmitHelpers;
let externalHelpersModule: Symbol;
const Symbol = objectAllocator.getSymbolConstructor();
const Type = objectAllocator.getTypeConstructor();
@@ -3064,7 +3066,15 @@ namespace ts {
}
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type {
Debug.assert(!!(source.flags & TypeFlags.Object), "Rest types only support object types right now.");
source = filterType(source, t => !(t.flags & TypeFlags.Nullable));
if (source.flags & TypeFlags.Never) {
return emptyObjectType;
}
if (source.flags & TypeFlags.Union) {
return mapType(source, t => getRestType(t, properties, symbol));
}
const members = createMap<Symbol>();
const names = createMap<true>();
for (const name of properties) {
@@ -3105,7 +3115,7 @@ namespace ts {
let type: Type;
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
if (declaration.dotDotDotToken) {
if (!(parentType.flags & TypeFlags.Object)) {
if (!isValidSpreadType(parentType)) {
error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types);
return unknownType;
}
@@ -3319,14 +3329,19 @@ namespace ts {
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
const members = createMap<Symbol>();
let stringIndexInfo: IndexInfo;
let hasComputedProperties = false;
forEach(pattern.elements, e => {
const name = e.propertyName || <Identifier>e.name;
if (isComputedNonLiteralName(name) || e.dotDotDotToken) {
// do not include computed properties or rests in the implied type
if (isComputedNonLiteralName(name)) {
// do not include computed properties in the implied type
hasComputedProperties = true;
return;
}
if (e.dotDotDotToken) {
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
return;
}
const text = getTextOfPropertyName(name);
const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
@@ -3335,7 +3350,7 @@ namespace ts {
symbol.bindingElement = e;
members[symbol.name] = symbol;
});
const result = createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined);
const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined);
if (includePatternInType) {
result.pattern = pattern;
}
@@ -4509,20 +4524,21 @@ namespace ts {
function resolveMappedTypeMembers(type: MappedType) {
const members: SymbolTable = createMap<Symbol>();
let stringIndexInfo: IndexInfo;
let numberIndexInfo: IndexInfo;
// Resolve upfront such that recursive references see an empty object type.
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
// and T as the template type.
// and T as the template type. If K is of the form 'keyof S', the mapped type and S are
// homomorphic and we copy property modifiers from corresponding properties in S.
const typeParameter = getTypeParameterFromMappedType(type);
const constraintType = getConstraintTypeFromMappedType(type);
const homomorphicType = getHomomorphicTypeFromMappedType(type);
const templateType = getTemplateTypeFromMappedType(type);
const isReadonly = !!type.declaration.readonlyToken;
const isOptional = !!type.declaration.questionToken;
const templateReadonly = !!type.declaration.readonlyToken;
const templateOptional = !!type.declaration.questionToken;
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
// if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
// Finally, iterate over the constituents of the resulting iteration type.
const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentType(constraintType) : constraintType;
const keyType = constraintType.flags & TypeFlags.TypeVariable ? getApparentType(constraintType) : constraintType;
const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
forEachType(iterationType, t => {
// Create a mapper from T to the current iteration type constituent. Then, if the
@@ -4531,29 +4547,22 @@ namespace ts {
const iterationMapper = createUnaryTypeMapper(typeParameter, t);
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
const propType = instantiateType(templateType, templateMapper);
// If the current iteration type constituent is a literal type, create a property.
// Otherwise, for type string create a string index signature and for type number
// create a numeric index signature.
if (t.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
// If the current iteration type constituent is a string literal type, create a property.
// Otherwise, for type string create a string index signature.
if (t.flags & TypeFlags.StringLiteral) {
const propName = (<LiteralType>t).text;
const homomorphicProp = homomorphicType && getPropertyOfType(homomorphicType, propName);
const isOptional = templateOptional || !!(homomorphicProp && homomorphicProp.flags & SymbolFlags.Optional);
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
prop.type = addOptionality(propType, isOptional);
prop.isReadonly = isReadonly;
prop.type = propType;
prop.isReadonly = templateReadonly || homomorphicProp && isReadonlySymbol(homomorphicProp);
members[propName] = prop;
}
else if (t.flags & TypeFlags.String) {
stringIndexInfo = createIndexInfo(propType, isReadonly);
}
else if (t.flags & TypeFlags.Number) {
numberIndexInfo = createIndexInfo(propType, isReadonly);
stringIndexInfo = createIndexInfo(propType, templateReadonly);
}
});
// If we created both a string and a numeric string index signature, and if the two index
// signatures have identical types, discard the redundant numeric index signature.
if (stringIndexInfo && numberIndexInfo && isTypeIdenticalTo(stringIndexInfo.type, numberIndexInfo.type)) {
numberIndexInfo = undefined;
}
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
}
function getTypeParameterFromMappedType(type: MappedType) {
@@ -4569,10 +4578,15 @@ namespace ts {
function getTemplateTypeFromMappedType(type: MappedType) {
return type.templateType ||
(type.templateType = type.declaration.type ?
instantiateType(getTypeFromTypeNode(type.declaration.type), type.mapper || identityMapper) :
instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) :
unknownType);
}
function getHomomorphicTypeFromMappedType(type: MappedType) {
const constraint = getConstraintDeclaration(getTypeParameterFromMappedType(type));
return constraint.kind === SyntaxKind.TypeOperator ? instantiateType(getTypeFromTypeNode((<TypeOperatorNode>constraint).type), type.mapper || identityMapper) : undefined;
}
function getErasedTemplateTypeFromMappedType(type: MappedType) {
return instantiateType(getTemplateTypeFromMappedType(type), createUnaryTypeMapper(getTypeParameterFromMappedType(type), anyType));
}
@@ -4580,7 +4594,7 @@ namespace ts {
function isGenericMappedType(type: Type) {
if (getObjectFlags(type) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>type);
return !!(constraintType.flags & (TypeFlags.TypeParameter | TypeFlags.Index));
return maybeTypeOfKind(constraintType, TypeFlags.TypeVariable | TypeFlags.Index);
}
return false;
}
@@ -5652,6 +5666,7 @@ namespace ts {
containsString?: boolean;
containsNumber?: boolean;
containsStringOrNumberLiteral?: boolean;
unionIndex?: number;
}
function binarySearchTypes(types: Type[], type: Type): number {
@@ -5846,6 +5861,9 @@ namespace ts {
typeSet.containsAny = true;
}
else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
if (type.flags & TypeFlags.Union && typeSet.unionIndex === undefined) {
typeSet.unionIndex = typeSet.length;
}
typeSet.push(type);
}
}
@@ -5872,15 +5890,6 @@ namespace ts {
if (types.length === 0) {
return emptyObjectType;
}
for (let i = 0; i < types.length; i++) {
const type = types[i];
if (type.flags & TypeFlags.Union) {
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
return getUnionType(map((<UnionType>type).types, t => getIntersectionType(replaceElement(types, i, t))),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
}
const typeSet = [] as TypeSet;
addTypesToIntersection(typeSet, types);
if (typeSet.containsAny) {
@@ -5889,6 +5898,14 @@ namespace ts {
if (typeSet.length === 1) {
return typeSet[0];
}
const unionIndex = typeSet.unionIndex;
if (unionIndex !== undefined) {
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
const unionType = <UnionType>typeSet[unionIndex];
return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
const id = getTypeListId(typeSet);
let type = intersectionTypes[id];
if (!type) {
@@ -5910,7 +5927,7 @@ namespace ts {
return links.resolvedType;
}
function getIndexTypeForTypeParameter(type: TypeParameter) {
function getIndexTypeForGenericType(type: TypeVariable | UnionOrIntersectionType) {
if (!type.resolvedIndexType) {
type.resolvedIndexType = <IndexType>createType(TypeFlags.Index);
type.resolvedIndexType.type = type;
@@ -5929,7 +5946,7 @@ namespace ts {
}
function getIndexType(type: Type): Type {
return type.flags & TypeFlags.TypeParameter ? getIndexTypeForTypeParameter(<TypeParameter>type) :
return maybeTypeOfKind(type, TypeFlags.TypeVariable) ? getIndexTypeForGenericType(<TypeVariable | UnionOrIntersectionType>type) :
getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(<MappedType>type) :
type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType :
getLiteralTypeFromPropertyNames(type);
@@ -6026,17 +6043,18 @@ namespace ts {
}
const mapper = createUnaryTypeMapper(getTypeParameterFromMappedType(type), indexType);
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
return addOptionality(instantiateType(getTemplateTypeFromMappedType(type), templateMapper), !!type.declaration.questionToken);
return instantiateType(getTemplateTypeFromMappedType(type), templateMapper);
}
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {
if (indexType.flags & TypeFlags.TypeParameter ||
objectType.flags & TypeFlags.TypeParameter && indexType.flags & TypeFlags.Index ||
isGenericMappedType(objectType)) {
// If either the object type or the index type are type parameters, or if the object type is a mapped
// type with a generic constraint, we are performing a higher-order index access where we cannot
// meaningfully access the properties of the object type. In those cases, we first check that the
// index type is assignable to 'keyof T' for the object type.
if (maybeTypeOfKind(indexType, TypeFlags.TypeVariable | TypeFlags.Index) || isGenericMappedType(objectType)) {
if (objectType.flags & TypeFlags.Any) {
return objectType;
}
// If the index type is generic or if the object type is a mapped type with a generic constraint,
// we are performing a higher-order index access where we cannot meaningfully access the properties
// of the object type. In those cases, we first check that the index type is assignable to 'keyof T'
// for the object type.
if (accessNode) {
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
@@ -6123,11 +6141,25 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): ResolvedType | IntrinsicType {
Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread.");
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
left = filterType(left, t => !(t.flags & TypeFlags.Nullable));
if (left.flags & TypeFlags.Never) {
return right;
}
right = filterType(right, t => !(t.flags & TypeFlags.Nullable));
if (right.flags & TypeFlags.Never) {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, isFromObjectLiteral));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, isFromObjectLiteral));
}
const members = createMap<Symbol>();
const skippedPrivateMembers = createMap<boolean>();
let stringIndexInfo: IndexInfo;
@@ -6515,19 +6547,19 @@ namespace ts {
}
function instantiateMappedType(type: MappedType, mapper: TypeMapper): Type {
// Check if we have an isomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some
// type parameter T. If so, the mapped type is distributive over a union type and when T is instantiated
// Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some
// type variable T. If so, the mapped type is distributive over a union type and when T is instantiated
// to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for
// isomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
// homomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a
// union type A | undefined, we produce { [P in keyof A]: X } | undefined.
const constraintType = getConstraintTypeFromMappedType(type);
if (constraintType.flags & TypeFlags.Index) {
const typeParameter = (<IndexType>constraintType).type;
const mappedTypeParameter = mapper(typeParameter);
if (typeParameter !== mappedTypeParameter) {
return mapType(mappedTypeParameter, t => {
const typeVariable = (<IndexType>constraintType).type;
const mappedTypeVariable = instantiateType(typeVariable, mapper);
if (typeVariable !== mappedTypeVariable) {
return mapType(mappedTypeVariable, t => {
if (isMappableType(t)) {
const replacementMapper = createUnaryTypeMapper(typeParameter, t);
const replacementMapper = createUnaryTypeMapper(typeVariable, t);
const combinedMapper = mapper.mappedTypes && mapper.mappedTypes.length === 1 ? replacementMapper : combineTypeMappers(replacementMapper, mapper);
combinedMapper.mappedTypes = mapper.mappedTypes;
return instantiateMappedObjectType(type, combinedMapper);
@@ -7260,10 +7292,12 @@ namespace ts {
}
// Given a type parameter T with a constraint C, a type S is assignable to
// keyof T if S is assignable to keyof C.
const constraint = getConstraintOfTypeParameter((<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
return result;
if ((<IndexType>target).type.flags & TypeFlags.TypeParameter) {
const constraint = getConstraintOfTypeParameter(<TypeParameter>(<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
return result;
}
}
}
}
@@ -8444,28 +8478,78 @@ namespace ts {
// Return true if the given type could possibly reference a type parameter for which
// we perform type inference (i.e. a type parameter of a generic function). We cache
// results for union and intersection types for performance reasons.
function couldContainTypeParameters(type: Type): boolean {
function couldContainTypeVariables(type: Type): boolean {
const objectFlags = getObjectFlags(type);
return !!(type.flags & TypeFlags.TypeParameter ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
return !!(type.flags & TypeFlags.TypeVariable ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
objectFlags & ObjectFlags.Mapped ||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeParameters(<UnionOrIntersectionType>type));
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(<UnionOrIntersectionType>type));
}
function couldUnionOrIntersectionContainTypeParameters(type: UnionOrIntersectionType): boolean {
if (type.couldContainTypeParameters === undefined) {
type.couldContainTypeParameters = forEach(type.types, couldContainTypeParameters);
function couldUnionOrIntersectionContainTypeVariables(type: UnionOrIntersectionType): boolean {
if (type.couldContainTypeVariables === undefined) {
type.couldContainTypeVariables = forEach(type.types, couldContainTypeVariables);
}
return type.couldContainTypeParameters;
return type.couldContainTypeVariables;
}
function isTypeParameterAtTopLevel(type: Type, typeParameter: TypeParameter): boolean {
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
}
function inferTypes(context: InferenceContext, originalSource: Type, originalTarget: Type) {
const typeParameters = context.signature.typeParameters;
// Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
// an object type with the same set of properties as the source type, where the type of each
// property is computed by inferring from the source property type to X for the type
// variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
function inferTypeForHomomorphicMappedType(source: Type, target: MappedType): Type {
const properties = getPropertiesOfType(source);
let indexInfo = getIndexInfoOfType(source, IndexKind.String);
if (properties.length === 0 && !indexInfo) {
return undefined;
}
const typeVariable = <TypeVariable>getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const typeVariableArray = [typeVariable];
const typeInferences = createTypeInferencesObject();
const typeInferencesArray = [typeInferences];
const templateType = getTemplateTypeFromMappedType(target);
const readonlyMask = target.declaration.readonlyToken ? false : true;
const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
const members = createSymbolTable(properties);
for (const prop of properties) {
const inferredPropType = inferTargetType(getTypeOfSymbol(prop));
if (!inferredPropType) {
return undefined;
}
const inferredProp = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | prop.flags & optionalMask, prop.name);
inferredProp.declarations = prop.declarations;
inferredProp.type = inferredPropType;
inferredProp.isReadonly = readonlyMask && isReadonlySymbol(prop);
members[prop.name] = inferredProp;
}
if (indexInfo) {
const inferredIndexType = inferTargetType(indexInfo.type);
if (!inferredIndexType) {
return undefined;
}
indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly);
}
return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined);
function inferTargetType(sourceType: Type): Type {
typeInferences.primary = undefined;
typeInferences.secondary = undefined;
inferTypes(typeVariableArray, typeInferencesArray, sourceType, templateType);
const inferences = typeInferences.primary || typeInferences.secondary;
return inferences && getUnionType(inferences, /*subtypeReduction*/ true);
}
}
function inferTypesWithContext(context: InferenceContext, originalSource: Type, originalTarget: Type) {
inferTypes(context.signature.typeParameters, context.inferences, originalSource, originalTarget);
}
function inferTypes(typeVariables: TypeVariable[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
let sourceStack: Type[];
let targetStack: Type[];
let depth = 0;
@@ -8483,7 +8567,7 @@ namespace ts {
}
function inferFromTypes(source: Type, target: Type) {
if (!couldContainTypeParameters(target)) {
if (!couldContainTypeVariables(target)) {
return;
}
if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
@@ -8533,7 +8617,7 @@ namespace ts {
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, matchingTypes);
}
}
if (target.flags & TypeFlags.TypeParameter) {
if (target.flags & TypeFlags.TypeVariable) {
// If target is a type parameter, make an inference, unless the source type contains
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
@@ -8543,9 +8627,9 @@ namespace ts {
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
return;
}
for (let i = 0; i < typeParameters.length; i++) {
if (target === typeParameters[i]) {
const inferences = context.inferences[i];
for (let i = 0; i < typeVariables.length; i++) {
if (target === typeVariables[i]) {
const inferences = typeInferences[i];
if (!inferences.isFixed) {
// Any inferences that are made to a type parameter in a union type are inferior
// to inferences made to a flat (non-union) type. This is because if we infer to
@@ -8559,7 +8643,7 @@ namespace ts {
if (!contains(candidates, source)) {
candidates.push(source);
}
if (!isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
if (target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
inferences.topLevel = false;
}
}
@@ -8578,24 +8662,24 @@ namespace ts {
}
else if (target.flags & TypeFlags.UnionOrIntersection) {
const targetTypes = (<UnionOrIntersectionType>target).types;
let typeParameterCount = 0;
let typeParameter: TypeParameter;
// First infer to each type in union or intersection that isn't a type parameter
let typeVariableCount = 0;
let typeVariable: TypeVariable;
// First infer to each type in union or intersection that isn't a type variable
for (const t of targetTypes) {
if (t.flags & TypeFlags.TypeParameter && contains(typeParameters, t)) {
typeParameter = <TypeParameter>t;
typeParameterCount++;
if (t.flags & TypeFlags.TypeVariable && contains(typeVariables, t)) {
typeVariable = <TypeVariable>t;
typeVariableCount++;
}
else {
inferFromTypes(source, t);
}
}
// Next, if target containings a single naked type parameter, make a secondary inference to that type
// parameter. This gives meaningful results for union types in co-variant positions and intersection
// Next, if target containings a single naked type variable, make a secondary inference to that type
// variable. This gives meaningful results for union types in co-variant positions and intersection
// types in contra-variant positions (such as callback parameters).
if (typeParameterCount === 1) {
if (typeVariableCount === 1) {
inferiority++;
inferFromTypes(source, typeParameter);
inferFromTypes(source, typeVariable);
inferiority--;
}
}
@@ -8636,12 +8720,25 @@ namespace ts {
function inferFromObjectTypes(source: Type, target: Type) {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (getObjectFlags(source) & ObjectFlags.Mapped) {
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
if (constraintType.flags & TypeFlags.Index) {
// We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
// where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
// type and then make a secondary inference from that type to T. We make a secondary inference
// such that direct inferences to T get priority over inferences to Partial<T>, for example.
const index = indexOf(typeVariables, (<IndexType>constraintType).type);
if (index >= 0 && !typeInferences[index].isFixed) {
const inferredType = inferTypeForHomomorphicMappedType(source, <MappedType>target);
if (inferredType) {
inferiority++;
inferFromTypes(inferredType, typeVariables[index]);
inferiority--;
}
}
return;
}
if (constraintType.flags & TypeFlags.TypeParameter) {
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
inferFromTypes(getIndexType(source), constraintType);
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
return;
@@ -11380,7 +11477,8 @@ namespace ts {
if (impliedProp) {
prop.flags |= impliedProp.flags & SymbolFlags.Optional;
}
else if (!compilerOptions.suppressExcessPropertyErrors) {
else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, IndexKind.String)) {
error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
symbolToString(member), typeToString(contextualType));
}
@@ -11396,6 +11494,9 @@ namespace ts {
member = prop;
}
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
if (languageVersion < ScriptTarget.ESNext) {
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
}
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
propertiesArray = [];
@@ -11405,7 +11506,7 @@ namespace ts {
typeFlags = 0;
}
const type = checkExpression((memberDecl as SpreadAssignment).expression);
if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) {
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return unknownType;
}
@@ -11483,6 +11584,12 @@ namespace ts {
}
}
function isValidSpreadType(type: Type): boolean {
return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined) ||
type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
type.flags & TypeFlags.UnionOrIntersection && !forEach((<UnionOrIntersectionType>type).types, t => !isValidSpreadType(t)));
}
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
checkJsxOpeningLikeElement(node);
return jsxElementType || anyType;
@@ -11583,6 +11690,9 @@ namespace ts {
}
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
if (compilerOptions.jsx === JsxEmit.React) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Assign);
}
const type = checkExpression(node.expression);
const props = getPropertiesOfType(type);
for (const prop of props) {
@@ -12483,7 +12593,7 @@ namespace ts {
const context = createInferenceContext(signature, /*inferUnionTypes*/ true);
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypes(context, instantiateType(source, contextualMapper), target);
inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
});
return getSignatureInstantiation(signature, getInferredTypes(context));
}
@@ -12518,7 +12628,7 @@ namespace ts {
if (thisType) {
const thisArgumentNode = getThisArgumentOfCall(node);
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
inferTypes(context, thisArgumentType, thisType);
inferTypesWithContext(context, thisArgumentType, thisType);
}
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
@@ -12540,7 +12650,7 @@ namespace ts {
argType = checkExpressionWithContextualType(arg, paramType, mapper);
}
inferTypes(context, argType, paramType);
inferTypesWithContext(context, argType, paramType);
}
}
@@ -12555,7 +12665,7 @@ namespace ts {
if (excludeArgument[i] === false) {
const arg = args[i];
const paramType = getTypeAtPosition(signature, i);
inferTypes(context, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
inferTypesWithContext(context, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
}
}
}
@@ -13642,7 +13752,7 @@ namespace ts {
for (let i = 0; i < len; i++) {
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
if (declaration.type) {
inferTypes(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
inferTypesWithContext(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
}
}
}
@@ -13728,7 +13838,7 @@ namespace ts {
// T in the second overload so that we do not infer Base as a candidate for T
// (inferring Base would make type argument inference inconsistent between the two
// overloads).
inferTypes(mapper.context, links.type, instantiateType(contextualType, mapper));
inferTypesWithContext(mapper.context, links.type, instantiateType(contextualType, mapper));
}
}
@@ -13864,7 +13974,7 @@ namespace ts {
if (!switchTypes.length) {
return false;
}
return eachTypeContainedIn(type, switchTypes);
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
}
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
@@ -14303,7 +14413,7 @@ namespace ts {
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) {
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
@@ -14348,6 +14458,9 @@ namespace ts {
}
}
else if (property.kind === SyntaxKind.SpreadAssignment) {
if (languageVersion < ScriptTarget.ESNext) {
checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
}
const nonRestNames: PropertyName[] = [];
if (allProperties) {
for (let i = 0; i < allProperties.length - 1; i++) {
@@ -15260,6 +15373,13 @@ namespace ts {
checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
}
if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
if (languageVersion < ScriptTarget.ES2015) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
}
}
checkTypeParameters(node.typeParameters);
forEach(node.parameters, checkParameter);
@@ -16395,7 +16515,15 @@ namespace ts {
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
}
const firstDecorator = node.decorators[0];
checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate);
if (node.kind === SyntaxKind.Parameter) {
checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param);
}
if (compilerOptions.emitDecoratorMetadata) {
checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
// we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
@@ -16782,7 +16910,7 @@ namespace ts {
}
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
if (!needCollisionCheckForIdentifier(node, name, "Promise")) {
if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
return;
}
@@ -16959,6 +17087,9 @@ namespace ts {
}
if (node.kind === SyntaxKind.BindingElement) {
if (node.parent.kind === SyntaxKind.ObjectBindingPattern && languageVersion < ScriptTarget.ESNext) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest);
}
// check computed properties inside property names of binding elements
if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
checkComputedPropertyName(<ComputedPropertyName>node.propertyName);
@@ -17225,7 +17356,7 @@ namespace ts {
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
@@ -17876,6 +18007,10 @@ namespace ts {
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
if (baseTypeNode) {
if (languageVersion < ScriptTarget.ES2015) {
checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends);
}
const baseTypes = getBaseTypes(type);
if (baseTypes.length && produceDiagnostics) {
const baseType = baseTypes[0];
@@ -20316,8 +20451,6 @@ namespace ts {
// Initialize global symbol table
let augmentations: LiteralExpression[][];
let requestedExternalEmitHelpers: NodeFlags = 0;
let firstFileRequestingExternalHelpers: SourceFile;
for (const file of host.getSourceFiles()) {
if (!isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
@@ -20337,15 +20470,6 @@ namespace ts {
}
}
}
if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) {
const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags;
if (fileRequestedExternalEmitHelpers) {
requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers;
if (firstFileRequestingExternalHelpers === undefined) {
firstFileRequestingExternalHelpers = file;
}
}
}
}
if (augmentations) {
@@ -20411,57 +20535,51 @@ namespace ts {
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
}
// If we have specified that we are importing helpers, we should report global
// errors if we cannot resolve the helpers external module, or if it does not have
// the necessary helpers exported.
if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) {
// Find the first reference to the helpers module.
const helpersModule = resolveExternalModule(
firstFileRequestingExternalHelpers,
externalHelpersModuleNameText,
Diagnostics.Cannot_find_module_0,
/*errorNode*/ undefined);
// If we found the module, report errors if it does not have the necessary exports.
if (helpersModule) {
const exports = helpersModule.exports;
if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute &&
(languageVersion < ScriptTarget.ESNext || compilerOptions.jsx === JsxEmit.React)) {
verifyHelperSymbol(exports, "__assign", SymbolFlags.Value);
}
if (languageVersion < ScriptTarget.ESNext && requestedExternalEmitHelpers & NodeFlags.HasRestAttribute) {
verifyHelperSymbol(exports, "__rest", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) {
verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value);
if (compilerOptions.emitDecoratorMetadata) {
verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value);
}
}
if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) {
verifyHelperSymbol(exports, "__param", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
if (languageVersion < ScriptTarget.ES2015) {
verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(location);
if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
const helpersModule = resolveHelpersModule(sourceFile, location);
if (helpersModule !== unknownSymbol) {
const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) {
if (uncheckedHelpers & helper) {
const name = getHelperName(helper);
const symbol = getSymbol(helpersModule.exports, escapeIdentifier(name), SymbolFlags.Value);
if (!symbol) {
error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
}
}
}
}
requestedExternalEmitHelpers |= helpers;
}
}
}
function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) {
const symbol = getSymbol(symbols, escapeIdentifier(name), meaning);
if (!symbol) {
error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
function getHelperName(helper: ExternalEmitHelpers) {
switch (helper) {
case ExternalEmitHelpers.Extends: return "__extends";
case ExternalEmitHelpers.Assign: return "__assign";
case ExternalEmitHelpers.Rest: return "__rest";
case ExternalEmitHelpers.Decorate: return "__decorate";
case ExternalEmitHelpers.Metadata: return "__metadata";
case ExternalEmitHelpers.Param: return "__param";
case ExternalEmitHelpers.Awaiter: return "__awaiter";
case ExternalEmitHelpers.Generator: return "__generator";
}
}
function resolveHelpersModule(node: SourceFile, errorNode: Node) {
if (!externalHelpersModule) {
externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
}
return externalHelpersModule;
}
function createInstantiatedPromiseLikeType(): ObjectType {
const promiseLikeType = getGlobalPromiseLikeType();
if (promiseLikeType !== emptyGenericType) {
@@ -21206,6 +21324,9 @@ namespace ts {
else if (accessor.body === undefined && !(getModifierFlags(accessor) & ModifierFlags.Abstract)) {
return grammarErrorAtPos(getSourceFileOfNode(accessor), accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
}
else if (accessor.body && getModifierFlags(accessor) & ModifierFlags.Abstract) {
return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
}
else if (accessor.typeParameters) {
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
}
+1 -1
View File
@@ -272,7 +272,7 @@ namespace ts {
"es2017": ScriptTarget.ES2017,
"esnext": ScriptTarget.ESNext,
}),
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT,
paramType: Diagnostics.VERSION,
},
{
+6
View File
@@ -1625,6 +1625,12 @@ namespace ts {
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
case SyntaxKind.IndexSignature:
// Interfaces cannot have parameter types that cannot be named
return symbolAccessibilityResult.errorModuleName ?
Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
if (hasModifier(node.parent, ModifierFlags.Static)) {
+21 -1
View File
@@ -851,6 +851,10 @@
"category": "Error",
"code": 1317
},
"An abstract accessor cannot have an implementation.": {
"category": "Error",
"code": 1318
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
@@ -1023,6 +1027,10 @@
"category": "Error",
"code": 2342
},
"This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'.": {
"category": "Error",
"code": 2343
},
"Type '{0}' does not satisfy the constraint '{1}'.": {
"category": "Error",
"code": 2344
@@ -1063,6 +1071,10 @@
"category": "Error",
"code": 2353
},
"This syntax requires an imported helper but module '{0}' cannot be found.": {
"category": "Error",
"code": 2354
},
"A function whose declared type is neither 'void' nor 'any' must return a value.": {
"category": "Error",
"code": 2355
@@ -2288,6 +2300,14 @@
"category": "Message",
"code": 4090
},
"Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4091
},
"Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.": {
"category": "Error",
"code": 4092
},
"The current host does not support the '{0}' option.": {
"category": "Error",
@@ -2453,7 +2473,7 @@
"category": "Message",
"code": 6012
},
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'": {
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'": {
"category": "Message",
"code": 6015
},
+3
View File
@@ -2558,6 +2558,8 @@ namespace ts {
case SyntaxKind.OpenBraceToken:
case SyntaxKind.OpenBracketToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.BarToken:
case SyntaxKind.AmpersandToken:
case SyntaxKind.NewKeyword:
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
@@ -2617,6 +2619,7 @@ namespace ts {
}
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
parseOptional(operator);
let type = parseConstituentType();
if (token() === operator) {
const types = createNodeArray<TypeNode>([type], type.pos);
+1 -1
View File
@@ -459,7 +459,7 @@ namespace ts {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
+2 -1
View File
@@ -345,6 +345,7 @@ namespace ts {
case SyntaxKind.PropertyDeclaration:
// TypeScript property declarations are elided.
return undefined;
case SyntaxKind.Constructor:
return visitConstructor(<ConstructorDeclaration>node);
@@ -1905,7 +1906,7 @@ namespace ts {
: (<ComputedPropertyName>name).expression;
}
else if (isIdentifier(name)) {
return createLiteral(name.text);
return createLiteral(unescapeIdentifier(name.text));
}
else {
return getSynthesizedClone(name);
+47 -25
View File
@@ -418,26 +418,20 @@ namespace ts {
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope
HasClassExtends = 1 << 10, // If the file has a non-ambient class with an extends clause in ES5 or lower (initialized by binding)
HasDecorators = 1 << 11, // If the file has decorators (initialized by binding)
HasParamDecorators = 1 << 12, // If the file has parameter decorators (initialized by binding)
HasAsyncFunctions = 1 << 13, // If the file has async functions (initialized by binding)
HasSpreadAttribute = 1 << 14, // If the file as JSX spread attributes (initialized by binding)
HasRestAttribute = 1 << 15, // If the file has object destructure elements
DisallowInContext = 1 << 16, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 17, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 18, // If node was parsed as part of a decorator
AwaitContext = 1 << 19, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 20, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 21, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 22, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 23, // If we've computed data from children and cached it in this node
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
BlockScoped = Let | Const,
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions | HasSpreadAttribute | HasRestAttribute,
ReachabilityAndEmitFlags = ReachabilityCheckFlags | EmitHelperFlags,
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
// Parsing context flags
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile,
@@ -2808,6 +2802,7 @@ namespace ts {
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
StructuredOrTypeParameter = StructuredType | TypeParameter | Index,
TypeVariable = TypeParameter | IndexedAccess,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
@@ -2920,7 +2915,9 @@ namespace ts {
/* @internal */
resolvedProperties: SymbolTable; // Cache of resolved properties
/* @internal */
couldContainTypeParameters: boolean;
resolvedIndexType: IndexType;
/* @internal */
couldContainTypeVariables: boolean;
}
export interface UnionType extends UnionOrIntersectionType { }
@@ -2976,8 +2973,13 @@ namespace ts {
iteratorElementType?: Type;
}
export interface TypeVariable extends Type {
/* @internal */
resolvedIndexType: IndexType;
}
// Type parameters (TypeFlags.TypeParameter)
export interface TypeParameter extends Type {
export interface TypeParameter extends TypeVariable {
constraint: Type; // Constraint
/* @internal */
target?: TypeParameter; // Instantiation target
@@ -2986,20 +2988,21 @@ namespace ts {
/* @internal */
resolvedApparentType: Type;
/* @internal */
resolvedIndexType: IndexType;
/* @internal */
isThisType?: boolean;
}
export interface IndexType extends Type {
type: TypeParameter;
}
export interface IndexedAccessType extends Type {
// Indexed access types (TypeFlags.IndexedAccess)
// Possible forms are T[xxx], xxx[T], or xxx[keyof T], where T is a type variable
export interface IndexedAccessType extends TypeVariable {
objectType: Type;
indexType: Type;
}
// keyof T types (TypeFlags.Index)
export interface IndexType extends Type {
type: TypeVariable | UnionOrIntersectionType;
}
export const enum SignatureKind {
Call,
Construct,
@@ -3705,6 +3708,25 @@ namespace ts {
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
}
/**
* Used by the checker, this enum keeps track of external emit helpers that should be type
* checked.
*/
/* @internal */
export const enum ExternalEmitHelpers {
Extends = 1 << 0, // __extends (used by the ES2015 class transformation)
Assign = 1 << 1, // __assign (used by Jsx and ESNext object spread transformations)
Rest = 1 << 2, // __rest (used by ESNext object rest transformation)
Decorate = 1 << 3, // __decorate (used by TypeScript decorators transformation)
Metadata = 1 << 4, // __metadata (used by TypeScript decorators transformation)
Param = 1 << 5, // __param (used by TypeScript decorators transformation)
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
FirstEmitHelper = Extends,
LastEmitHelper = Generator
}
/* @internal */
export const enum EmitContext {
SourceFile, // Emitting a SourceFile
+4
View File
@@ -423,6 +423,10 @@ namespace ts {
return false;
}
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
return isExternalModule(node) || compilerOptions.isolatedModules;
}
export function isBlockScope(node: Node, parentNode: Node) {
switch (node.kind) {
case SyntaxKind.SourceFile:
+60 -2
View File
@@ -51,9 +51,8 @@ namespace ts.projectSystem {
throttleLimit: number,
installTypingHost: server.ServerHost,
readonly typesRegistry = createMap<void>(),
telemetryEnabled?: boolean,
log?: TI.Log) {
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, telemetryEnabled, log);
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, log);
}
safeFileList = safeList.path;
@@ -2729,6 +2728,65 @@ namespace ts.projectSystem {
arguments: { projectFileName: projectName }
}).response;
assert.isTrue(diags.length === 0);
session.executeCommand(<server.protocol.SetCompilerOptionsForInferredProjectsRequest>{
type: "request",
command: server.CommandNames.CompilerOptionsForInferredProjects,
seq: 3,
arguments: { options: { module: ModuleKind.CommonJS } }
});
const diagsAfterUpdate = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
type: "request",
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
seq: 4,
arguments: { projectFileName: projectName }
}).response;
assert.isTrue(diagsAfterUpdate.length === 0);
});
it("for external project", () => {
const f1 = {
path: "/a/b/f1.js",
content: "function test1() { }"
};
const host = createServerHost([f1, libFile]);
const session = createSession(host);
const projectService = session.getProjectService();
const projectFileName = "/a/b/project.csproj";
const externalFiles = toExternalFiles([f1.path]);
projectService.openExternalProject(<protocol.ExternalProject>{
projectFileName,
rootFiles: externalFiles,
options: {}
});
checkNumberOfProjects(projectService, { externalProjects: 1 });
const diags = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
type: "request",
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
seq: 2,
arguments: { projectFileName }
}).response;
assert.isTrue(diags.length === 0);
session.executeCommand(<server.protocol.OpenExternalProjectRequest>{
type: "request",
command: server.CommandNames.OpenExternalProject,
seq: 3,
arguments: {
projectFileName,
rootFiles: externalFiles,
options: { module: ModuleKind.CommonJS }
}
});
const diagsAfterUpdate = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
type: "request",
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
seq: 4,
arguments: { projectFileName }
}).response;
assert.isTrue(diagsAfterUpdate.length === 0);
});
});
+107 -7
View File
@@ -20,13 +20,12 @@ namespace ts.projectSystem {
}
class Installer extends TestTypingsInstaller {
constructor(host: server.ServerHost, p?: InstallerParams, telemetryEnabled?: boolean, log?: TI.Log) {
constructor(host: server.ServerHost, p?: InstallerParams, log?: TI.Log) {
super(
(p && p.globalTypingsCacheLocation) || "/a/data",
(p && p.throttleLimit) || 5,
host,
(p && p.typesRegistry),
telemetryEnabled,
log);
}
@@ -36,7 +35,7 @@ namespace ts.projectSystem {
}
}
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[], typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
self.addPostExecAction(installedTypings, success => {
for (const file of typingFiles) {
host.createFileOrFolder(file, /*createParentDirectory*/ true);
@@ -907,7 +906,7 @@ namespace ts.projectSystem {
const host = createServerHost([f1, packageJson]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" }, /*telemetryEnabled*/ false, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
}
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
assert(false, "runCommand should not be invoked");
@@ -971,15 +970,18 @@ namespace ts.projectSystem {
let seenTelemetryEvent = false;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") }, /*telemetryEnabled*/ true);
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.TypingsInstallEvent) {
if (response.kind === server.EventInstall) {
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
return;
}
if (response.kind === server.EventEndInstallTypes) {
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
seenTelemetryEvent = true;
return;
@@ -997,4 +999,102 @@ namespace ts.projectSystem {
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
});
});
describe("progress notifications", () => {
it ("should be sent for success", () => {
const f1 = {
path: "/a/app.js",
content: ""
};
const package = {
path: "/a/package.json",
content: JSON.stringify({ dependencies: { "commander": "1.0.0" } })
};
const cachePath = "/a/cache/";
const commander = {
path: cachePath + "node_modules/@types/commander/index.d.ts",
content: "export let x: number"
};
const host = createServerHost([f1, package]);
let beginEvent: server.BeginInstallTypes;
let endEvent: server.EndInstallTypes;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
beginEvent = response;
return;
}
if (response.kind === server.EventEndInstallTypes) {
endEvent = response;
return;
}
super.sendResponse(response);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert.isTrue(endEvent.installSuccess);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
});
it ("should be sent for error", () => {
const f1 = {
path: "/a/app.js",
content: ""
};
const package = {
path: "/a/package.json",
content: JSON.stringify({ dependencies: { "commander": "1.0.0" } })
};
const cachePath = "/a/cache/";
const host = createServerHost([f1, package]);
let beginEvent: server.BeginInstallTypes;
let endEvent: server.EndInstallTypes;
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeCommand(this, host, "", [], cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
if (response.kind === server.EventBeginInstallTypes) {
beginEvent = response;
return;
}
if (response.kind === server.EventEndInstallTypes) {
endEvent = response;
return;
}
super.sendResponse(response);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert.isFalse(endEvent.installSuccess);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]);
});
});
}
+12 -1
View File
@@ -4,11 +4,22 @@ interface ObjectConstructor {
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values<T>(o: { [s: string]: T }): T[];
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values(o: any): any[];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T }): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T extends { [key: string]: any }, K extends keyof T>(o: T): [keyof T, T[K]][];
entries(o: any): [string, any][];
}
+8 -3
View File
@@ -248,9 +248,7 @@ namespace ts.server {
this.compilerOptions.allowNonTsExtensions = true;
}
if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) {
this.compilerOptions.noEmitForJsFiles = true;
}
this.setInternalCompilerOptionsForEmittingJsFiles();
this.lsHost = new LSHost(this.projectService.host, this, this.projectService.cancellationToken);
this.lsHost.setCompilationSettings(this.compilerOptions);
@@ -266,6 +264,12 @@ namespace ts.server {
this.markAsDirty();
}
private setInternalCompilerOptionsForEmittingJsFiles() {
if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) {
this.compilerOptions.noEmitForJsFiles = true;
}
}
getProjectErrors() {
return this.projectErrors;
}
@@ -637,6 +641,7 @@ namespace ts.server {
this.lastCachedUnresolvedImportsList = undefined;
}
this.compilerOptions = compilerOptions;
this.setInternalCompilerOptionsForEmittingJsFiles();
this.lsHost.setCompilationSettings(compilerOptions);
this.markAsDirty();
+34
View File
@@ -2117,6 +2117,40 @@ namespace ts.server.protocol {
typingsInstallerVersion: string;
}
export type BeginInstallTypesEventName = "beginInstallTypes";
export type EndInstallTypesEventName = "endInstallTypes";
export interface BeginInstallTypesEvent extends Event {
event: BeginInstallTypesEventName;
body: BeginInstallTypesEventBody;
}
export interface EndInstallTypesEvent extends Event {
event: EndInstallTypesEventName;
body: EndInstallTypesEventBody;
}
export interface InstallTypesEventBody {
/**
* correlation id to match begin and end events
*/
eventId: number;
/**
* list of packages to install
*/
packages: ReadonlyArray<string>;
}
export interface BeginInstallTypesEventBody extends InstallTypesEventBody {
}
export interface EndInstallTypesEventBody extends InstallTypesEventBody {
/**
* true if installation succeeded, otherwise false
*/
success: boolean;
}
export interface NavBarResponse extends Response {
body?: NavigationBarItem[];
}
+59 -25
View File
@@ -20,34 +20,41 @@ namespace ts.server {
} = require("os");
function getGlobalTypingsCacheLocation() {
let basePath: string;
switch (process.platform) {
case "win32":
basePath = process.env.LOCALAPPDATA ||
case "win32": {
const basePath = process.env.LOCALAPPDATA ||
process.env.APPDATA ||
(os.homedir && os.homedir()) ||
process.env.USERPROFILE ||
(process.env.HOMEDRIVE && process.env.HOMEPATH && normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) ||
os.tmpdir();
break;
case "linux":
case "android":
basePath = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/home/${process.env.LOGNAME || process.env.USER}`) ||
os.tmpdir();
break;
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
}
case "darwin":
const homeDir = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/Users/${process.env.LOGNAME || process.env.USER}`) ||
os.tmpdir();
basePath = combinePaths(homeDir, "Library/Application Support/");
break;
case "linux":
case "android": {
const cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin");
return combinePaths(cacheLocation, "typescript");
}
default:
Debug.fail(`unsupported platform '${process.platform}'`);
return;
}
}
Debug.assert(basePath !== undefined);
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
function getNonWindowsCacheLocation(platformIsDarwin: boolean) {
if (process.env.XDG_CACHE_HOME) {
return process.env.XDG_CACHE_HOME;
}
const usersDir = platformIsDarwin ? "Users" : "home"
const homePath = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/${usersDir}/${process.env.LOGNAME || process.env.USER}`) ||
os.tmpdir();
const cacheFolder = platformIsDarwin
? "Library/Caches"
: ".cache"
return combinePaths(normalizeSlashes(homePath), cacheFolder);
}
interface NodeChildProcess {
@@ -198,7 +205,7 @@ namespace ts.server {
private socket: NodeSocket;
private projectService: ProjectService;
private throttledOperations: ThrottledOperations;
private telemetrySender: EventSender;
private eventSender: EventSender;
constructor(
private readonly telemetryEnabled: boolean,
@@ -231,7 +238,7 @@ namespace ts.server {
}
setTelemetrySender(telemetrySender: EventSender) {
this.telemetrySender = telemetrySender;
this.eventSender = telemetrySender;
}
attach(projectService: ProjectService) {
@@ -291,12 +298,30 @@ namespace ts.server {
});
}
private handleMessage(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent) {
private handleMessage(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes) {
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Received response: ${JSON.stringify(response)}`);
}
if (response.kind === EventInstall) {
if (this.telemetrySender) {
if (response.kind === EventBeginInstallTypes) {
if (!this.eventSender) {
return;
}
const body: protocol.BeginInstallTypesEventBody = {
eventId: response.eventId,
packages: response.packagesToInstall,
};
const eventName: protocol.BeginInstallTypesEventName = "beginInstallTypes";
this.eventSender.event(body, eventName);
return;
}
if (response.kind === EventEndInstallTypes) {
if (!this.eventSender) {
return;
}
if (this.telemetryEnabled) {
const body: protocol.TypingsInstalledTelemetryEventBody = {
telemetryEventName: "typingsInstalled",
payload: {
@@ -306,10 +331,19 @@ namespace ts.server {
}
};
const eventName: protocol.TelemetryEventName = "telemetry";
this.telemetrySender.event(body, eventName);
this.eventSender.event(body, eventName);
}
const body: protocol.EndInstallTypesEventBody = {
eventId: response.eventId,
packages: response.packagesToInstall,
success: response.installSuccess,
};
const eventName: protocol.EndInstallTypesEventName = "endInstallTypes";
this.eventSender.event(body, eventName);
return;
}
this.projectService.updateTypingsForProject(response);
if (response.kind == ActionSet && this.socket) {
this.sendEvent(0, "setTypings", response);
+2 -1
View File
@@ -3,7 +3,8 @@
namespace ts.server {
export const ActionSet: ActionSet = "action::set";
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
export const EventInstall: EventInstall = "event::install";
export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes";
export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes";
export namespace Arguments {
export const GlobalCacheLocation = "--globalTypingsCacheLocation";
+16 -6
View File
@@ -43,10 +43,11 @@ declare namespace ts.server {
export type ActionSet = "action::set";
export type ActionInvalidate = "action::invalidate";
export type EventInstall = "event::install";
export type EventBeginInstallTypes = "event::beginInstallTypes";
export type EventEndInstallTypes = "event::endInstallTypes";
export interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventInstall;
readonly kind: ActionSet | ActionInvalidate | EventBeginInstallTypes | EventEndInstallTypes;
}
export interface ProjectResponse extends TypingInstallerResponse {
@@ -65,11 +66,20 @@ declare namespace ts.server {
readonly kind: ActionInvalidate;
}
export interface TypingsInstallEvent extends TypingInstallerResponse {
readonly packagesToInstall: ReadonlyArray<string>;
readonly kind: EventInstall;
readonly installSuccess: boolean;
export interface InstallTypes extends ProjectResponse {
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
readonly eventId: number;
readonly typingsInstallerVersion: string;
readonly packagesToInstall: ReadonlyArray<string>;
}
export interface BeginInstallTypes extends InstallTypes {
readonly kind: EventBeginInstallTypes;
}
export interface EndInstallTypes extends InstallTypes {
readonly kind: EventEndInstallTypes;
readonly installSuccess: boolean;
}
export interface InstallTypingHost extends JsTyping.TypingResolutionHost {
@@ -70,13 +70,12 @@ namespace ts.server.typingsInstaller {
private readonly npmPath: string;
readonly typesRegistry: Map<void>;
constructor(globalTypingsCacheLocation: string, throttleLimit: number, telemetryEnabled: boolean, log: Log) {
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
telemetryEnabled,
log);
if (this.log.isEnabled()) {
this.log.writeLine(`Process id: ${process.pid}`);
@@ -113,7 +112,7 @@ namespace ts.server.typingsInstaller {
});
}
protected sendResponse(response: SetTypings | InvalidateCachedTypings) {
protected sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes) {
if (this.log.isEnabled()) {
this.log.writeLine(`Sending response: ${JSON.stringify(response)}`);
}
@@ -149,7 +148,6 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const telemetryEnabled = hasArgument(server.Arguments.EnableTelemetry);
const log = new FileLog(logFilePath);
if (log.isEnabled()) {
@@ -163,6 +161,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, telemetryEnabled, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log);
installer.listen();
}
+47 -37
View File
@@ -97,7 +97,6 @@ namespace ts.server.typingsInstaller {
readonly globalCachePath: string,
readonly safeListPath: Path,
readonly throttleLimit: number,
readonly telemetryEnabled: boolean,
protected readonly log = nullLog) {
if (this.log.isEnabled()) {
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`);
@@ -309,47 +308,58 @@ namespace ts.server.typingsInstaller {
const requestId = this.installRunCount;
this.installRunCount++;
// send progress event
this.sendResponse(<BeginInstallTypes>{
kind: EventBeginInstallTypes,
eventId: requestId,
typingsInstallerVersion: ts.version, // qualified explicitly to prevent occasional shadowing
projectName: req.projectName
});
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
if (this.telemetryEnabled) {
this.sendResponse(<TypingsInstallEvent>{
kind: EventInstall,
try {
if (!ok) {
if (this.log.isEnabled()) {
this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
}
for (const typing of filteredTypings) {
this.missingTypingsSet[typing] = true;
}
return;
}
// TODO: watch project directory
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`);
}
const installedTypingFiles: string[] = [];
for (const packageName of filteredTypings) {
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
if (!typingFile) {
this.missingTypingsSet[packageName] = true;
continue;
}
if (!this.packageNameToTypingLocation[packageName]) {
this.packageNameToTypingLocation[packageName] = typingFile;
}
installedTypingFiles.push(typingFile);
}
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
}
this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
}
finally {
this.sendResponse(<EndInstallTypes>{
kind: EventEndInstallTypes,
eventId: requestId,
projectName: req.projectName,
packagesToInstall: scopedTypings,
installSuccess: ok,
typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing
});
}
if (!ok) {
if (this.log.isEnabled()) {
this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
}
for (const typing of filteredTypings) {
this.missingTypingsSet[typing] = true;
}
return;
}
// TODO: watch project directory
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`);
}
const installedTypingFiles: string[] = [];
for (const packageName of filteredTypings) {
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
if (!typingFile) {
this.missingTypingsSet[packageName] = true;
continue;
}
if (!this.packageNameToTypingLocation[packageName]) {
this.packageNameToTypingLocation[packageName] = typingFile;
}
installedTypingFiles.push(typingFile);
}
if (this.log.isEnabled()) {
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
}
this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
});
}
@@ -417,6 +427,6 @@ namespace ts.server.typingsInstaller {
}
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
}
}
@@ -0,0 +1,17 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts(4,17): error TS1318: An abstract accessor cannot have an implementation.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts(6,17): error TS1318: An abstract accessor cannot have an implementation.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts (2 errors) ====
abstract class A {
abstract get a();
abstract get aa() { return 1; } // error
~~
!!! error TS1318: An abstract accessor cannot have an implementation.
abstract set b(x: string);
abstract set bb(x: string) {} // error
~~
!!! error TS1318: An abstract accessor cannot have an implementation.
}
@@ -0,0 +1,28 @@
//// [classAbstractAccessor.ts]
abstract class A {
abstract get a();
abstract get aa() { return 1; } // error
abstract set b(x: string);
abstract set bb(x: string) {} // error
}
//// [classAbstractAccessor.js]
var A = (function () {
function A() {
}
Object.defineProperty(A.prototype, "aa", {
get: function () { return 1; } // error
,
enumerable: true,
configurable: true
});
Object.defineProperty(A.prototype, "bb", {
set: function (x) { } // error
,
enumerable: true,
configurable: true
});
return A;
}());
@@ -0,0 +1,17 @@
tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,6): error TS1023: An index signature parameter type must be 'string' or 'number'.
tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,13): error TS2304: Cannot find name 'TypeNotFound'.
tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,13): error TS4092: Parameter 'index' of index signature from exported interface has or is using private name 'TypeNotFound'.
==== tests/cases/compiler/declarationEmitIndexTypeNotFound.ts (3 errors) ====
export interface Test {
[index: TypeNotFound]: any;
~~~~~
!!! error TS1023: An index signature parameter type must be 'string' or 'number'.
~~~~~~~~~~~~
!!! error TS2304: Cannot find name 'TypeNotFound'.
~~~~~~~~~~~~
!!! error TS4092: Parameter 'index' of index signature from exported interface has or is using private name 'TypeNotFound'.
}
@@ -0,0 +1,9 @@
//// [declarationEmitIndexTypeNotFound.ts]
export interface Test {
[index: TypeNotFound]: any;
}
//// [declarationEmitIndexTypeNotFound.js]
"use strict";
@@ -0,0 +1,37 @@
//// [decoratorWithUnderscoreMethod.ts]
declare var console : { log(arg: string): void };
function dec(): Function {
return function (target: any, propKey: string, descr: PropertyDescriptor): void {
console.log(target[propKey]);
//logs undefined
//propKey has three underscores as prefix, but the method has only two underscores
};
}
class A {
@dec()
private __foo(bar: string): void {
// do something with bar
}
}
//// [decoratorWithUnderscoreMethod.js]
function dec() {
return function (target, propKey, descr) {
console.log(target[propKey]);
//logs undefined
//propKey has three underscores as prefix, but the method has only two underscores
};
}
var A = (function () {
function A() {
}
A.prototype.__foo = function (bar) {
// do something with bar
};
return A;
}());
__decorate([
dec()
], A.prototype, "__foo");
@@ -0,0 +1,42 @@
=== tests/cases/compiler/decoratorWithUnderscoreMethod.ts ===
declare var console : { log(arg: string): void };
>console : Symbol(console, Decl(decoratorWithUnderscoreMethod.ts, 1, 11))
>log : Symbol(log, Decl(decoratorWithUnderscoreMethod.ts, 1, 23))
>arg : Symbol(arg, Decl(decoratorWithUnderscoreMethod.ts, 1, 28))
function dec(): Function {
>dec : Symbol(dec, Decl(decoratorWithUnderscoreMethod.ts, 1, 49))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
return function (target: any, propKey: string, descr: PropertyDescriptor): void {
>target : Symbol(target, Decl(decoratorWithUnderscoreMethod.ts, 3, 21))
>propKey : Symbol(propKey, Decl(decoratorWithUnderscoreMethod.ts, 3, 33))
>descr : Symbol(descr, Decl(decoratorWithUnderscoreMethod.ts, 3, 50))
>PropertyDescriptor : Symbol(PropertyDescriptor, Decl(lib.d.ts, --, --))
console.log(target[propKey]);
>console.log : Symbol(log, Decl(decoratorWithUnderscoreMethod.ts, 1, 23))
>console : Symbol(console, Decl(decoratorWithUnderscoreMethod.ts, 1, 11))
>log : Symbol(log, Decl(decoratorWithUnderscoreMethod.ts, 1, 23))
>target : Symbol(target, Decl(decoratorWithUnderscoreMethod.ts, 3, 21))
>propKey : Symbol(propKey, Decl(decoratorWithUnderscoreMethod.ts, 3, 33))
//logs undefined
//propKey has three underscores as prefix, but the method has only two underscores
};
}
class A {
>A : Symbol(A, Decl(decoratorWithUnderscoreMethod.ts, 8, 1))
@dec()
>dec : Symbol(dec, Decl(decoratorWithUnderscoreMethod.ts, 1, 49))
private __foo(bar: string): void {
>__foo : Symbol(A.__foo, Decl(decoratorWithUnderscoreMethod.ts, 10, 9))
>bar : Symbol(bar, Decl(decoratorWithUnderscoreMethod.ts, 12, 18))
// do something with bar
}
}
@@ -0,0 +1,46 @@
=== tests/cases/compiler/decoratorWithUnderscoreMethod.ts ===
declare var console : { log(arg: string): void };
>console : { log(arg: string): void; }
>log : (arg: string) => void
>arg : string
function dec(): Function {
>dec : () => Function
>Function : Function
return function (target: any, propKey: string, descr: PropertyDescriptor): void {
>function (target: any, propKey: string, descr: PropertyDescriptor): void { console.log(target[propKey]); //logs undefined //propKey has three underscores as prefix, but the method has only two underscores } : (target: any, propKey: string, descr: PropertyDescriptor) => void
>target : any
>propKey : string
>descr : PropertyDescriptor
>PropertyDescriptor : PropertyDescriptor
console.log(target[propKey]);
>console.log(target[propKey]) : void
>console.log : (arg: string) => void
>console : { log(arg: string): void; }
>log : (arg: string) => void
>target[propKey] : any
>target : any
>propKey : string
//logs undefined
//propKey has three underscores as prefix, but the method has only two underscores
};
}
class A {
>A : A
@dec()
>dec() : Function
>dec : () => Function
private __foo(bar: string): void {
>__foo : (bar: string) => void
>bar : string
// do something with bar
}
}
@@ -0,0 +1,39 @@
//// [exhaustiveSwitchWithWideningLiteralTypes.ts]
// Repro from #12529
class A {
readonly kind = "A"; // (property) A.kind: "A"
}
class B {
readonly kind = "B"; // (property) B.kind: "B"
}
function f(value: A | B): number {
switch(value.kind) {
case "A": return 0;
case "B": return 1;
}
}
//// [exhaustiveSwitchWithWideningLiteralTypes.js]
// Repro from #12529
var A = (function () {
function A() {
this.kind = "A"; // (property) A.kind: "A"
}
return A;
}());
var B = (function () {
function B() {
this.kind = "B"; // (property) B.kind: "B"
}
return B;
}());
function f(value) {
switch (value.kind) {
case "A": return 0;
case "B": return 1;
}
}
@@ -0,0 +1,33 @@
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
// Repro from #12529
class A {
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
readonly kind = "A"; // (property) A.kind: "A"
>kind : Symbol(A.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9))
}
class B {
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
readonly kind = "B"; // (property) B.kind: "B"
>kind : Symbol(B.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
}
function f(value: A | B): number {
>f : Symbol(f, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 9, 1))
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
switch(value.kind) {
>value.kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
>kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
case "A": return 0;
case "B": return 1;
}
}
@@ -0,0 +1,40 @@
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
// Repro from #12529
class A {
>A : A
readonly kind = "A"; // (property) A.kind: "A"
>kind : "A"
>"A" : "A"
}
class B {
>B : B
readonly kind = "B"; // (property) B.kind: "B"
>kind : "B"
>"B" : "B"
}
function f(value: A | B): number {
>f : (value: A | B) => number
>value : A | B
>A : A
>B : B
switch(value.kind) {
>value.kind : "A" | "B"
>value : A | B
>kind : "A" | "B"
case "A": return 0;
>"A" : "A"
>0 : 0
case "B": return 1;
>"B" : "B"
>1 : 1
}
}
@@ -1,32 +1,38 @@
error TS2305: Module 'tslib' has no exported member '__assign'.
error TS2305: Module 'tslib' has no exported member '__decorate'.
error TS2305: Module 'tslib' has no exported member '__extends'.
error TS2305: Module 'tslib' has no exported member '__metadata'.
error TS2305: Module 'tslib' has no exported member '__param'.
error TS2305: Module 'tslib' has no exported member '__rest'.
tests/cases/compiler/external.ts(2,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'.
tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'.
tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'.
tests/cases/compiler/external.ts(8,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'.
tests/cases/compiler/external.ts(13,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'.
tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
!!! error TS2305: Module 'tslib' has no exported member '__assign'.
!!! error TS2305: Module 'tslib' has no exported member '__decorate'.
!!! error TS2305: Module 'tslib' has no exported member '__extends'.
!!! error TS2305: Module 'tslib' has no exported member '__metadata'.
!!! error TS2305: Module 'tslib' has no exported member '__param'.
!!! error TS2305: Module 'tslib' has no exported member '__rest'.
==== tests/cases/compiler/external.ts (0 errors) ====
==== tests/cases/compiler/external.ts (6 errors) ====
export class A { }
export class B extends A { }
~~~~~~~~~
!!! error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'.
declare var dec: any;
@dec
~~~~
!!! error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'.
~~~~
!!! error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'.
class C {
method(@dec x: number) {
~~~~
!!! error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'.
}
}
const o = { a: 1 };
const y = { ...o };
~~~~
!!! error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'.
const { ...x } = y;
~
!!! error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
==== tests/cases/compiler/script.ts (0 errors) ====
class A { }
@@ -1,10 +1,11 @@
error TS2307: Cannot find module 'tslib'.
tests/cases/compiler/external.ts(2,16): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found.
!!! error TS2307: Cannot find module 'tslib'.
==== tests/cases/compiler/external.ts (0 errors) ====
==== tests/cases/compiler/external.ts (1 errors) ====
export class A { }
export class B extends A { }
~~~~~~~~~
!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found.
declare var dec: any;
@@ -58,6 +58,51 @@ function getValueAsString(value: IntersectionFail): string {
return '' + value.num;
}
return value.str;
}
// Repro from #12535
namespace enums {
export const enum A {
a1,
a2,
a3,
// ... elements omitted for the sake of clarity
a75,
a76,
a77,
}
export const enum B {
b1,
b2,
// ... elements omitted for the sake of clarity
b86,
b87,
}
export const enum C {
c1,
c2,
// ... elements omitted for the sake of clarity
c210,
c211,
}
export type Genre = A | B | C;
}
type Foo = {
genreId: enums.Genre;
};
type Bar = {
genreId: enums.Genre;
};
type FooBar = Foo & Bar;
function foo(so: any) {
const val = so as FooBar;
const isGenre = val.genreId;
return isGenre;
}
//// [intersectionTypeNormalization.js]
@@ -77,3 +122,8 @@ function getValueAsString(value) {
}
return value.str;
}
function foo(so) {
var val = so;
var isGenre = val.genreId;
return isGenre;
}
@@ -240,3 +240,113 @@ function getValueAsString(value: IntersectionFail): string {
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
}
// Repro from #12535
namespace enums {
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
export const enum A {
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
a1,
>a1 : Symbol(A.a1, Decl(intersectionTypeNormalization.ts, 64, 25))
a2,
>a2 : Symbol(A.a2, Decl(intersectionTypeNormalization.ts, 65, 11))
a3,
>a3 : Symbol(A.a3, Decl(intersectionTypeNormalization.ts, 66, 11))
// ... elements omitted for the sake of clarity
a75,
>a75 : Symbol(A.a75, Decl(intersectionTypeNormalization.ts, 67, 11))
a76,
>a76 : Symbol(A.a76, Decl(intersectionTypeNormalization.ts, 69, 12))
a77,
>a77 : Symbol(A.a77, Decl(intersectionTypeNormalization.ts, 70, 12))
}
export const enum B {
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
b1,
>b1 : Symbol(B.b1, Decl(intersectionTypeNormalization.ts, 73, 25))
b2,
>b2 : Symbol(B.b2, Decl(intersectionTypeNormalization.ts, 74, 11))
// ... elements omitted for the sake of clarity
b86,
>b86 : Symbol(B.b86, Decl(intersectionTypeNormalization.ts, 75, 11))
b87,
>b87 : Symbol(B.b87, Decl(intersectionTypeNormalization.ts, 77, 12))
}
export const enum C {
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
c1,
>c1 : Symbol(C.c1, Decl(intersectionTypeNormalization.ts, 80, 25))
c2,
>c2 : Symbol(C.c2, Decl(intersectionTypeNormalization.ts, 81, 11))
// ... elements omitted for the sake of clarity
c210,
>c210 : Symbol(C.c210, Decl(intersectionTypeNormalization.ts, 82, 11))
c211,
>c211 : Symbol(C.c211, Decl(intersectionTypeNormalization.ts, 84, 13))
}
export type Genre = A | B | C;
>Genre : Symbol(Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
}
type Foo = {
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
genreId: enums.Genre;
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12))
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
};
type Bar = {
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
genreId: enums.Genre;
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 94, 12))
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
};
type FooBar = Foo & Bar;
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
function foo(so: any) {
>foo : Symbol(foo, Decl(intersectionTypeNormalization.ts, 98, 24))
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
const val = so as FooBar;
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
const isGenre = val.genreId;
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
>val.genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
return isGenre;
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
}
@@ -244,3 +244,114 @@ function getValueAsString(value: IntersectionFail): string {
>value : { kind: "string"; str: string; } & ToString
>str : string
}
// Repro from #12535
namespace enums {
>enums : typeof enums
export const enum A {
>A : A
a1,
>a1 : A.a1
a2,
>a2 : A.a2
a3,
>a3 : A.a3
// ... elements omitted for the sake of clarity
a75,
>a75 : A.a75
a76,
>a76 : A.a76
a77,
>a77 : A.a77
}
export const enum B {
>B : B
b1,
>b1 : B.b1
b2,
>b2 : B.b2
// ... elements omitted for the sake of clarity
b86,
>b86 : B.b86
b87,
>b87 : B.b87
}
export const enum C {
>C : C
c1,
>c1 : C.c1
c2,
>c2 : C.c2
// ... elements omitted for the sake of clarity
c210,
>c210 : C.c210
c211,
>c211 : C.c211
}
export type Genre = A | B | C;
>Genre : Genre
>A : A
>B : B
>C : C
}
type Foo = {
>Foo : Foo
genreId: enums.Genre;
>genreId : enums.Genre
>enums : any
>Genre : enums.Genre
};
type Bar = {
>Bar : Bar
genreId: enums.Genre;
>genreId : enums.Genre
>enums : any
>Genre : enums.Genre
};
type FooBar = Foo & Bar;
>FooBar : FooBar
>Foo : Foo
>Bar : Bar
function foo(so: any) {
>foo : (so: any) => enums.Genre
>so : any
const val = so as FooBar;
>val : FooBar
>so as FooBar : FooBar
>so : any
>FooBar : FooBar
const isGenre = val.genreId;
>isGenre : enums.Genre
>val.genreId : enums.Genre
>val : FooBar
>genreId : enums.Genre
return isGenre;
>isGenre : enums.Genre
}
@@ -0,0 +1,10 @@
//// [intersectionTypeWithLeadingOperator.ts]
type A = & string;
type B =
& { foo: string }
& { bar: number };
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
//// [intersectionTypeWithLeadingOperator.js]
@@ -0,0 +1,20 @@
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
type A = & string;
>A : Symbol(A, Decl(intersectionTypeWithLeadingOperator.ts, 0, 0))
type B =
>B : Symbol(B, Decl(intersectionTypeWithLeadingOperator.ts, 0, 18))
& { foo: string }
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 2, 5))
& { bar: number };
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 3, 5))
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
>C : Symbol(C, Decl(intersectionTypeWithLeadingOperator.ts, 3, 20))
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 13))
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 26))
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 40))
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 53))
@@ -0,0 +1,20 @@
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
type A = & string;
>A : string
type B =
>B : B
& { foo: string }
>foo : string
& { bar: number };
>bar : number
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
>C : [{ foo: 1; } & { bar: 2; }, { foo: 3; } & { bar: 4; }]
>foo : 1
>bar : 2
>foo : 3
>bar : 4
@@ -0,0 +1,330 @@
//// [isomorphicMappedTypeInference.ts]
type Box<T> = {
value: T;
}
type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
}
function box<T>(x: T): Box<T> {
return { value: x };
}
function unbox<T>(x: Box<T>): T {
return x.value;
}
function boxify<T>(obj: T): Boxified<T> {
let result = {} as Boxified<T>;
for (let k in obj) {
result[k] = box(obj[k]);
}
return result;
}
function unboxify<T>(obj: Boxified<T>): T {
let result = {} as T;
for (let k in obj) {
result[k] = unbox(obj[k]);
}
return result;
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
for (let k in values) {
obj[k].value = values[k];
}
}
function f1() {
let v = {
a: 42,
b: "hello",
c: true
};
let b = boxify(v);
let x: number = b.a.value;
}
function f2() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
let v = unboxify(b);
let x: number = v.a;
}
function f3() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
assignBoxified(b, { c: false });
}
function f4() {
let b = {
a: box(42),
b: box("hello"),
c: box(true)
};
b = boxify(unboxify(b));
b = unboxify(boxify(b));
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
return obj;
}
function f5(s: string) {
let b = makeRecord({
a: box(42),
b: box("hello"),
c: box(true)
});
let v = unboxify(b);
let x: string | number | boolean = v.a;
}
function makeDictionary<T>(obj: { [x: string]: T }) {
return obj;
}
function f6(s: string) {
let b = makeDictionary({
a: box(42),
b: box("hello"),
c: box(true)
});
let v = unboxify(b);
let x: string | number | boolean = v[s];
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
type Foo = {
a?: number;
readonly b: string;
}
function f10(foo: Foo) {
let x = validate(foo); // { a: number, readonly b: string }
let y = clone(foo); // { a?: number, b: string }
let z = validateAndClone(foo); // { a: number, b: string }
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
type Spec<T> = {
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
sum: (a: any) => 3,
nested: {
mul: (b: any) => "n"
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
// Repro from #12633
const foo = <T>(object: T, partial: Partial<T>) => object;
let o = {a: 5, b: 7};
foo(o, {b: 9});
o = foo(o, {b: 9});
//// [isomorphicMappedTypeInference.js]
function box(x) {
return { value: x };
}
function unbox(x) {
return x.value;
}
function boxify(obj) {
var result = {};
for (var k in obj) {
result[k] = box(obj[k]);
}
return result;
}
function unboxify(obj) {
var result = {};
for (var k in obj) {
result[k] = unbox(obj[k]);
}
return result;
}
function assignBoxified(obj, values) {
for (var k in values) {
obj[k].value = values[k];
}
}
function f1() {
var v = {
a: 42,
b: "hello",
c: true
};
var b = boxify(v);
var x = b.a.value;
}
function f2() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
var v = unboxify(b);
var x = v.a;
}
function f3() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
assignBoxified(b, { c: false });
}
function f4() {
var b = {
a: box(42),
b: box("hello"),
c: box(true)
};
b = boxify(unboxify(b));
b = unboxify(boxify(b));
}
function makeRecord(obj) {
return obj;
}
function f5(s) {
var b = makeRecord({
a: box(42),
b: box("hello"),
c: box(true)
});
var v = unboxify(b);
var x = v.a;
}
function makeDictionary(obj) {
return obj;
}
function f6(s) {
var b = makeDictionary({
a: box(42),
b: box("hello"),
c: box(true)
});
var v = unboxify(b);
var x = v[s];
}
function f10(foo) {
var x = validate(foo); // { a: number, readonly b: string }
var y = clone(foo); // { a?: number, b: string }
var z = validateAndClone(foo); // { a: number, b: string }
}
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
sum: function (a) { return 3; },
nested: {
mul: function (b) { return "n"; }
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: function (x) { return true; } } } });
// Repro from #12633
var foo = function (object, partial) { return object; };
var o = { a: 5, b: 7 };
foo(o, { b: 9 });
o = foo(o, { b: 9 });
//// [isomorphicMappedTypeInference.d.ts]
declare type Box<T> = {
value: T;
};
declare type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
};
declare function box<T>(x: T): Box<T>;
declare function unbox<T>(x: Box<T>): T;
declare function boxify<T>(obj: T): Boxified<T>;
declare function unboxify<T>(obj: Boxified<T>): T;
declare function assignBoxified<T>(obj: Boxified<T>, values: T): void;
declare function f1(): void;
declare function f2(): void;
declare function f3(): void;
declare function f4(): void;
declare function makeRecord<T, K extends string>(obj: {
[P in K]: T;
}): {
[P in K]: T;
};
declare function f5(s: string): void;
declare function makeDictionary<T>(obj: {
[x: string]: T;
}): {
[x: string]: T;
};
declare function f6(s: string): void;
declare function validate<T>(obj: {
[P in keyof T]?: T[P];
}): T;
declare function clone<T>(obj: {
readonly [P in keyof T]: T[P];
}): T;
declare function validateAndClone<T>(obj: {
readonly [P in keyof T]?: T[P];
}): T;
declare type Foo = {
a?: number;
readonly b: string;
};
declare function f10(foo: Foo): void;
declare type Func<T> = (...args: any[]) => T;
declare type Spec<T> = {
[P in keyof T]: Func<T[P]> | Spec<T[P]>;
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
declare var g1: (...args: any[]) => {
sum: number;
nested: {
mul: string;
};
};
declare var g2: (...args: any[]) => {
foo: {
bar: {
baz: boolean;
};
};
};
declare const foo: <T>(object: T, partial: Partial<T>) => T;
declare let o: {
a: number;
b: number;
};
@@ -0,0 +1,489 @@
=== tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts ===
type Box<T> = {
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 1, 9))
value: T;
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 1, 9))
}
type Boxified<T> = {
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
[P in keyof T]: Box<T[P]>;
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 6, 5))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 5, 14))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 6, 5))
}
function box<T>(x: T): Box<T> {
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 9, 16))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 9, 13))
return { value: x };
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 10, 12))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 9, 16))
}
function unbox<T>(x: Box<T>): T {
>unbox : Symbol(unbox, Decl(isomorphicMappedTypeInference.ts, 11, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 13, 18))
>Box : Symbol(Box, Decl(isomorphicMappedTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 13, 15))
return x.value;
>x.value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 13, 18))
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
}
function boxify<T>(obj: T): Boxified<T> {
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
let result = {} as Boxified<T>;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 17, 16))
for (let k in obj) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
result[k] = box(obj[k]);
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 17, 19))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 19, 12))
}
return result;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 18, 7))
}
function unboxify<T>(obj: Boxified<T>): T {
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
let result = {} as T;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 25, 18))
for (let k in obj) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
result[k] = unbox(obj[k]);
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
>unbox : Symbol(unbox, Decl(isomorphicMappedTypeInference.ts, 11, 1))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 25, 21))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 27, 12))
}
return result;
>result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 26, 7))
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
>assignBoxified : Symbol(assignBoxified, Decl(isomorphicMappedTypeInference.ts, 31, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 33, 27))
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 3, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 33, 24))
for (let k in values) {
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
obj[k].value = values[k];
>obj[k].value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 33, 27))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>values : Symbol(values, Decl(isomorphicMappedTypeInference.ts, 33, 44))
>k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 34, 12))
}
}
function f1() {
>f1 : Symbol(f1, Decl(isomorphicMappedTypeInference.ts, 37, 1))
let v = {
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 40, 7))
a: 42,
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 40, 13))
b: "hello",
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 41, 14))
c: true
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 42, 19))
};
let b = boxify(v);
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 45, 7))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 40, 7))
let x: number = b.a.value;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 46, 7))
>b.a.value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
>b.a : Symbol(a)
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 45, 7))
>a : Symbol(a)
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 1, 15))
}
function f2() {
>f2 : Symbol(f2, Decl(isomorphicMappedTypeInference.ts, 47, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 50, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 51, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 52, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 55, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 50, 7))
let x: number = v.a;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 56, 7))
>v.a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 55, 7))
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 50, 13))
}
function f3() {
>f3 : Symbol(f3, Decl(isomorphicMappedTypeInference.ts, 57, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 60, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 60, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 61, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 62, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
assignBoxified(b, { c: false });
>assignBoxified : Symbol(assignBoxified, Decl(isomorphicMappedTypeInference.ts, 31, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 60, 7))
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 65, 23))
}
function f4() {
>f4 : Symbol(f4, Decl(isomorphicMappedTypeInference.ts, 66, 1))
let b = {
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 69, 13))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 70, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 71, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
};
b = boxify(unboxify(b));
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
b = unboxify(boxify(b));
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>boxify : Symbol(boxify, Decl(isomorphicMappedTypeInference.ts, 15, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 69, 7))
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
>makeRecord : Symbol(makeRecord, Decl(isomorphicMappedTypeInference.ts, 76, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 78, 20))
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 78, 22))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 78, 41))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 78, 49))
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 78, 22))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 78, 20))
return obj;
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 78, 41))
}
function f5(s: string) {
>f5 : Symbol(f5, Decl(isomorphicMappedTypeInference.ts, 80, 1))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 82, 12))
let b = makeRecord({
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 83, 7))
>makeRecord : Symbol(makeRecord, Decl(isomorphicMappedTypeInference.ts, 76, 1))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 83, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 84, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 85, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
});
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 88, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 83, 7))
let x: string | number | boolean = v.a;
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 89, 7))
>v.a : Symbol(a)
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 88, 7))
>a : Symbol(a)
}
function makeDictionary<T>(obj: { [x: string]: T }) {
>makeDictionary : Symbol(makeDictionary, Decl(isomorphicMappedTypeInference.ts, 90, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 92, 24))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 92, 27))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 92, 35))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 92, 24))
return obj;
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 92, 27))
}
function f6(s: string) {
>f6 : Symbol(f6, Decl(isomorphicMappedTypeInference.ts, 94, 1))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 96, 12))
let b = makeDictionary({
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 97, 7))
>makeDictionary : Symbol(makeDictionary, Decl(isomorphicMappedTypeInference.ts, 90, 1))
a: box(42),
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 97, 28))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
b: box("hello"),
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 98, 19))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
c: box(true)
>c : Symbol(c, Decl(isomorphicMappedTypeInference.ts, 99, 24))
>box : Symbol(box, Decl(isomorphicMappedTypeInference.ts, 7, 1))
});
let v = unboxify(b);
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 102, 7))
>unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 23, 1))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 97, 7))
let x: string | number | boolean = v[s];
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 103, 7))
>v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 102, 7))
>s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 96, 12))
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 106, 29))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26))
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 107, 26))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23))
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 108, 37))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34))
type Foo = {
>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81))
a?: number;
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 110, 12))
readonly b: string;
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 111, 15))
}
function f10(foo: Foo) {
>f10 : Symbol(f10, Decl(isomorphicMappedTypeInference.ts, 113, 1))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81))
let x = validate(foo); // { a: number, readonly b: string }
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 116, 7))
>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
let y = clone(foo); // { a?: number, b: string }
>y : Symbol(y, Decl(isomorphicMappedTypeInference.ts, 117, 7))
>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
let z = validateAndClone(foo); // { a: number, b: string }
>z : Symbol(z, Decl(isomorphicMappedTypeInference.ts, 118, 7))
>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
>Func : Symbol(Func, Decl(isomorphicMappedTypeInference.ts, 119, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 123, 10))
>args : Symbol(args, Decl(isomorphicMappedTypeInference.ts, 123, 16))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 123, 10))
type Spec<T> = {
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>Func : Symbol(Func, Decl(isomorphicMappedTypeInference.ts, 119, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 133, 30))
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
>args : Symbol(args, Decl(isomorphicMappedTypeInference.ts, 133, 46))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : Symbol(g1, Decl(isomorphicMappedTypeInference.ts, 136, 3))
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
sum: (a: any) => 3,
>sum : Symbol(sum, Decl(isomorphicMappedTypeInference.ts, 136, 20))
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 137, 10))
nested: {
>nested : Symbol(nested, Decl(isomorphicMappedTypeInference.ts, 137, 23))
mul: (b: any) => "n"
>mul : Symbol(mul, Decl(isomorphicMappedTypeInference.ts, 138, 13))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 139, 14))
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : Symbol(g2, Decl(isomorphicMappedTypeInference.ts, 144, 3))
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 144, 20))
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 144, 27))
>baz : Symbol(baz, Decl(isomorphicMappedTypeInference.ts, 144, 34))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 144, 41))
// Repro from #12633
const foo = <T>(object: T, partial: Partial<T>) => object;
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 148, 5))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 148, 13))
>object : Symbol(object, Decl(isomorphicMappedTypeInference.ts, 148, 16))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 148, 13))
>partial : Symbol(partial, Decl(isomorphicMappedTypeInference.ts, 148, 26))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 148, 13))
>object : Symbol(object, Decl(isomorphicMappedTypeInference.ts, 148, 16))
let o = {a: 5, b: 7};
>o : Symbol(o, Decl(isomorphicMappedTypeInference.ts, 149, 3))
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 149, 9))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 149, 14))
foo(o, {b: 9});
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 148, 5))
>o : Symbol(o, Decl(isomorphicMappedTypeInference.ts, 149, 3))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 150, 8))
o = foo(o, {b: 9});
>o : Symbol(o, Decl(isomorphicMappedTypeInference.ts, 149, 3))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 148, 5))
>o : Symbol(o, Decl(isomorphicMappedTypeInference.ts, 149, 3))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 151, 12))
@@ -0,0 +1,587 @@
=== tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts ===
type Box<T> = {
>Box : Box<T>
>T : T
value: T;
>value : T
>T : T
}
type Boxified<T> = {
>Boxified : Boxified<T>
>T : T
[P in keyof T]: Box<T[P]>;
>P : P
>T : T
>Box : Box<T>
>T : T
>P : P
}
function box<T>(x: T): Box<T> {
>box : <T>(x: T) => Box<T>
>T : T
>x : T
>T : T
>Box : Box<T>
>T : T
return { value: x };
>{ value: x } : { value: T; }
>value : T
>x : T
}
function unbox<T>(x: Box<T>): T {
>unbox : <T>(x: Box<T>) => T
>T : T
>x : Box<T>
>Box : Box<T>
>T : T
>T : T
return x.value;
>x.value : T
>x : Box<T>
>value : T
}
function boxify<T>(obj: T): Boxified<T> {
>boxify : <T>(obj: T) => Boxified<T>
>T : T
>obj : T
>T : T
>Boxified : Boxified<T>
>T : T
let result = {} as Boxified<T>;
>result : Boxified<T>
>{} as Boxified<T> : Boxified<T>
>{} : {}
>Boxified : Boxified<T>
>T : T
for (let k in obj) {
>k : keyof T
>obj : T
result[k] = box(obj[k]);
>result[k] = box(obj[k]) : Box<T[keyof T]>
>result[k] : Box<T[keyof T]>
>result : Boxified<T>
>k : keyof T
>box(obj[k]) : Box<T[keyof T]>
>box : <T>(x: T) => Box<T>
>obj[k] : T[keyof T]
>obj : T
>k : keyof T
}
return result;
>result : Boxified<T>
}
function unboxify<T>(obj: Boxified<T>): T {
>unboxify : <T>(obj: Boxified<T>) => T
>T : T
>obj : Boxified<T>
>Boxified : Boxified<T>
>T : T
>T : T
let result = {} as T;
>result : T
>{} as T : T
>{} : {}
>T : T
for (let k in obj) {
>k : keyof T
>obj : Boxified<T>
result[k] = unbox(obj[k]);
>result[k] = unbox(obj[k]) : T[keyof T]
>result[k] : T[keyof T]
>result : T
>k : keyof T
>unbox(obj[k]) : T[keyof T]
>unbox : <T>(x: Box<T>) => T
>obj[k] : Box<T[keyof T]>
>obj : Boxified<T>
>k : keyof T
}
return result;
>result : T
}
function assignBoxified<T>(obj: Boxified<T>, values: T) {
>assignBoxified : <T>(obj: Boxified<T>, values: T) => void
>T : T
>obj : Boxified<T>
>Boxified : Boxified<T>
>T : T
>values : T
>T : T
for (let k in values) {
>k : keyof T
>values : T
obj[k].value = values[k];
>obj[k].value = values[k] : T[keyof T]
>obj[k].value : T[keyof T]
>obj[k] : Box<T[keyof T]>
>obj : Boxified<T>
>k : keyof T
>value : T[keyof T]
>values[k] : T[keyof T]
>values : T
>k : keyof T
}
}
function f1() {
>f1 : () => void
let v = {
>v : { a: number; b: string; c: boolean; }
>{ a: 42, b: "hello", c: true } : { a: number; b: string; c: boolean; }
a: 42,
>a : number
>42 : 42
b: "hello",
>b : string
>"hello" : "hello"
c: true
>c : boolean
>true : true
};
let b = boxify(v);
>b : Boxified<{ a: number; b: string; c: boolean; }>
>boxify(v) : Boxified<{ a: number; b: string; c: boolean; }>
>boxify : <T>(obj: T) => Boxified<T>
>v : { a: number; b: string; c: boolean; }
let x: number = b.a.value;
>x : number
>b.a.value : number
>b.a : Box<number>
>b : Boxified<{ a: number; b: string; c: boolean; }>
>a : Box<number>
>value : number
}
function f2() {
>f2 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
let v = unboxify(b);
>v : { a: number; b: string; c: boolean; }
>unboxify(b) : { a: number; b: string; c: boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
let x: number = v.a;
>x : number
>v.a : number
>v : { a: number; b: string; c: boolean; }
>a : number
}
function f3() {
>f3 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
assignBoxified(b, { c: false });
>assignBoxified(b, { c: false }) : void
>assignBoxified : <T>(obj: Boxified<T>, values: T) => void
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ c: false } : { c: false; }
>c : boolean
>false : false
}
function f4() {
>f4 : () => void
let b = {
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
};
b = boxify(unboxify(b));
>b = boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>boxify : <T>(obj: T) => Boxified<T>
>unboxify(b) : { a: number; b: string; c: boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
b = unboxify(boxify(b));
>b = unboxify(boxify(b)) : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>unboxify(boxify(b)) : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>unboxify : <T>(obj: Boxified<T>) => T
>boxify(b) : Boxified<{ a: Box<number>; b: Box<string>; c: Box<boolean>; }>
>boxify : <T>(obj: T) => Boxified<T>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
}
function makeRecord<T, K extends string>(obj: { [P in K]: T }) {
>makeRecord : <T, K extends string>(obj: { [P in K]: T; }) => { [P in K]: T; }
>T : T
>K : K
>obj : { [P in K]: T; }
>P : P
>K : K
>T : T
return obj;
>obj : { [P in K]: T; }
}
function f5(s: string) {
>f5 : (s: string) => void
>s : string
let b = makeRecord({
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
>makeRecord({ a: box(42), b: box("hello"), c: box(true) }) : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
>makeRecord : <T, K extends string>(obj: { [P in K]: T; }) => { [P in K]: T; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
});
let v = unboxify(b);
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v.a;
>x : string | number | boolean
>v.a : string | number | boolean
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>a : string | number | boolean
}
function makeDictionary<T>(obj: { [x: string]: T }) {
>makeDictionary : <T>(obj: { [x: string]: T; }) => { [x: string]: T; }
>T : T
>obj : { [x: string]: T; }
>x : string
>T : T
return obj;
>obj : { [x: string]: T; }
}
function f6(s: string) {
>f6 : (s: string) => void
>s : string
let b = makeDictionary({
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
>makeDictionary({ a: box(42), b: box("hello"), c: box(true) }) : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
>makeDictionary : <T>(obj: { [x: string]: T; }) => { [x: string]: T; }
>{ a: box(42), b: box("hello"), c: box(true) } : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
a: box(42),
>a : Box<number>
>box(42) : Box<number>
>box : <T>(x: T) => Box<T>
>42 : 42
b: box("hello"),
>b : Box<string>
>box("hello") : Box<string>
>box : <T>(x: T) => Box<T>
>"hello" : "hello"
c: box(true)
>c : Box<boolean>
>box(true) : Box<boolean>
>box : <T>(x: T) => Box<T>
>true : true
});
let v = unboxify(b);
>v : { [x: string]: string | number | boolean; }
>unboxify(b) : { [x: string]: string | number | boolean; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v[s];
>x : string | number | boolean
>v[s] : string | number | boolean
>v : { [x: string]: string | number | boolean; }
>s : string
}
declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>T : T
>obj : { [P in keyof T]?: T[P] | undefined; }
>P : P
>T : T
>T : T
>P : P
>T : T
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>T : T
>obj : { readonly [P in keyof T]: T[P]; }
>P : P
>T : T
>T : T
>P : P
>T : T
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>T : T
>obj : { readonly [P in keyof T]?: T[P] | undefined; }
>P : P
>T : T
>T : T
>P : P
>T : T
type Foo = {
>Foo : Foo
a?: number;
>a : number | undefined
readonly b: string;
>b : string
}
function f10(foo: Foo) {
>f10 : (foo: Foo) => void
>foo : Foo
>Foo : Foo
let x = validate(foo); // { a: number, readonly b: string }
>x : { a: number; readonly b: string; }
>validate(foo) : { a: number; readonly b: string; }
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
let y = clone(foo); // { a?: number, b: string }
>y : { a?: number | undefined; b: string; }
>clone(foo) : { a?: number | undefined; b: string; }
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>foo : Foo
let z = validateAndClone(foo); // { a: number, b: string }
>z : { a: number; b: string; }
>validateAndClone(foo) : { a: number; b: string; }
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
>Func : Func<T>
>T : T
>args : any[]
>T : T
type Spec<T> = {
>Spec : Spec<T>
>T : T
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
>P : P
>T : T
>Func : Func<T>
>T : T
>P : P
>Spec : Spec<T>
>T : T
>P : P
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>T : T
>obj : Spec<T>
>Spec : Spec<T>
>T : T
>args : any[]
>T : T
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; }
sum: (a: any) => 3,
>sum : (a: any) => number
>(a: any) => 3 : (a: any) => number
>a : any
>3 : 3
nested: {
>nested : { mul: (b: any) => string; }
>{ mul: (b: any) => "n" } : { mul: (b: any) => string; }
mul: (b: any) => "n"
>mul : (b: any) => string
>(b: any) => "n" : (b: any) => string
>b : any
>"n" : "n"
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; }
>foo : { bar: { baz: (x: any) => boolean; }; }
>{ bar: { baz: (x: any) => true } } : { bar: { baz: (x: any) => boolean; }; }
>bar : { baz: (x: any) => boolean; }
>{ baz: (x: any) => true } : { baz: (x: any) => boolean; }
>baz : (x: any) => boolean
>(x: any) => true : (x: any) => boolean
>x : any
>true : true
// Repro from #12633
const foo = <T>(object: T, partial: Partial<T>) => object;
>foo : <T>(object: T, partial: Partial<T>) => T
><T>(object: T, partial: Partial<T>) => object : <T>(object: T, partial: Partial<T>) => T
>T : T
>object : T
>T : T
>partial : Partial<T>
>Partial : Partial<T>
>T : T
>object : T
let o = {a: 5, b: 7};
>o : { a: number; b: number; }
>{a: 5, b: 7} : { a: number; b: number; }
>a : number
>5 : 5
>b : number
>7 : 7
foo(o, {b: 9});
>foo(o, {b: 9}) : { a: number; b: number; }
>foo : <T>(object: T, partial: Partial<T>) => T
>o : { a: number; b: number; }
>{b: 9} : { b: number; }
>b : number
>9 : 9
o = foo(o, {b: 9});
>o = foo(o, {b: 9}) : { a: number; b: number; }
>o : { a: number; b: number; }
>foo(o, {b: 9}) : { a: number; b: number; }
>foo : <T>(object: T, partial: Partial<T>) => T
>o : { a: number; b: number; }
>{b: 9} : { b: number; }
>b : number
>9 : 9
@@ -21,11 +21,12 @@ class Options {
}
type Dictionary<T> = { [x: string]: T };
type NumericallyIndexed<T> = { [x: number]: T };
const enum E { A, B, C }
type K00 = keyof any; // string | number
type K01 = keyof string; // number | "toString" | "charAt" | ...
type K00 = keyof any; // string
type K01 = keyof string; // "toString" | "charAt" | ...
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
type K03 = keyof boolean; // "valueOf"
type K04 = keyof void; // never
@@ -34,19 +35,20 @@ type K06 = keyof null; // never
type K07 = keyof never; // never
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string | number
type K11 = keyof Shape[]; // "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string
type K13 = keyof {}; // never
type K14 = keyof Object; // "constructor" | "toString" | ...
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
type K17 = keyof (Shape | Item); // "name"
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
type K19 = keyof NumericallyIndexed<Shape> // never
type KeyOf<T> = keyof T;
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
type K21 = KeyOf<Dictionary<Shape>>; // string | number
type K21 = KeyOf<Dictionary<Shape>>; // string
type NAME = "name";
type WIDTH_OR_HEIGHT = "width" | "height";
@@ -217,6 +219,36 @@ function f60<T>(source: T, target: T) {
}
}
function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
func<{ a: any, b: any }, { a: any, c: any }>('a', 'a');
func<{ a: any, b: any }, { a: any, c: any }>('a', 'b');
func<{ a: any, b: any }, { a: any, c: any }>('a', 'c');
}
function f71(func: <T, U>(x: T, y: U) => Partial<T & U>) {
let x = func({ a: 1, b: "hello" }, { c: true });
x.a; // number | undefined
x.b; // string | undefined
x.c; // boolean | undefined
}
function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]) {
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
}
function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]) {
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
}
function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) {
let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number
let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean
}
// Repros from #12011
class Base {
@@ -247,6 +279,91 @@ class OtherPerson {
getParts() {
return getProperty(this, "parts")
}
}
// Modified repro from #12544
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
function path(obj: any, ...keys: (string | number)[]): any;
function path(obj: any, ...keys: (string | number)[]): any {
let result = obj;
for (let k of keys) {
result = result[k];
}
return result;
}
type Thing = {
a: { x: number, y: string },
b: boolean
};
function f1(thing: Thing) {
let x1 = path(thing, 'a'); // { x: number, y: string }
let x2 = path(thing, 'a', 'y'); // string
let x3 = path(thing, 'b'); // boolean
let x4 = path(thing, ...['a', 'x']); // any
}
// Repro from comment in #12114
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
(value: T[K1][K2]) => object[key1][key2] = value;
// Modified repro from #12573
declare function one<T>(handler: (t: T) => void): T
var empty = one(() => {}) // inferred as {}, expected
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
declare function on<T>(handlerHash: Handlers<T>): T
var hashOfEmpty1 = on({ test: () => {} }); // {}
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
// Repro from #12624
interface Options1<Data, Computed> {
data?: Data
computed?: Computed;
}
declare class Component1<Data, Computed> {
constructor(options: Options1<Data, Computed>);
get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K];
}
let c1 = new Component1({
data: {
hello: ""
}
});
c1.get("hello");
// Repro from #12625
interface Options2<Data, Computed> {
data?: Data
computed?: Computed;
}
declare class Component2<Data, Computed> {
constructor(options: Options2<Data, Computed>);
get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K];
}
// Repro from #12641
interface R {
p: number;
}
function f<K extends keyof R>(p: K) {
let a: any;
a[p].add; // any
}
//// [keyofAndIndexedAccess.js]
@@ -394,6 +511,31 @@ function f60(source, target) {
target[k] = source[k];
}
}
function f70(func) {
func('a', 'a');
func('a', 'b');
func('a', 'c');
}
function f71(func) {
var x = func({ a: 1, b: "hello" }, { c: true });
x.a; // number | undefined
x.b; // string | undefined
x.c; // boolean | undefined
}
function f72(func) {
var a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
var b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
var c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
}
function f73(func) {
var a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
var b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
var c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
}
function f74(func) {
var a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number
var b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean
}
// Repros from #12011
var Base = (function () {
function Base() {
@@ -427,6 +569,41 @@ var OtherPerson = (function () {
};
return OtherPerson;
}());
function path(obj) {
var keys = [];
for (var _i = 1; _i < arguments.length; _i++) {
keys[_i - 1] = arguments[_i];
}
var result = obj;
for (var _a = 0, keys_1 = keys; _a < keys_1.length; _a++) {
var k = keys_1[_a];
result = result[k];
}
return result;
}
function f1(thing) {
var x1 = path(thing, 'a'); // { x: number, y: string }
var x2 = path(thing, 'a', 'y'); // string
var x3 = path(thing, 'b'); // boolean
var x4 = path.apply(void 0, [thing].concat(['a', 'x'])); // any
}
// Repro from comment in #12114
var assignTo2 = function (object, key1, key2) {
return function (value) { return object[key1][key2] = value; };
};
var empty = one(function () { }); // inferred as {}, expected
var hashOfEmpty1 = on({ test: function () { } }); // {}
var hashOfEmpty2 = on({ test: function (x) { } }); // { test: boolean }
var c1 = new Component1({
data: {
hello: ""
}
});
c1.get("hello");
function f(p) {
var a;
a[p].add; // any
}
//// [keyofAndIndexedAccess.d.ts]
@@ -449,6 +626,9 @@ declare class Options {
declare type Dictionary<T> = {
[x: string]: T;
};
declare type NumericallyIndexed<T> = {
[x: number]: T;
};
declare const enum E {
A = 0,
B = 1,
@@ -471,6 +651,7 @@ declare type K15 = keyof E;
declare type K16 = keyof [string, number];
declare type K17 = keyof (Shape | Item);
declare type K18 = keyof (Shape & Item);
declare type K19 = keyof NumericallyIndexed<Shape>;
declare type KeyOf<T> = keyof T;
declare type K20 = KeyOf<Shape>;
declare type K21 = KeyOf<Dictionary<Shape>>;
@@ -530,6 +711,11 @@ declare function f53<T, K extends keyof T>(obj: {
declare function f54<T>(obj: T, key: keyof T): void;
declare function f55<T, K extends keyof T>(obj: T, key: K): void;
declare function f60<T>(source: T, target: T): void;
declare function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void): void;
declare function f71(func: <T, U>(x: T, y: U) => Partial<T & U>): void;
declare function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]): void;
declare function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]): void;
declare function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]): void;
declare class Base {
get<K extends keyof this>(prop: K): this[K];
set<K extends keyof this>(prop: K, value: this[K]): void;
@@ -544,3 +730,49 @@ declare class OtherPerson {
constructor(parts: number);
getParts(): number;
}
declare function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
declare function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
declare function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
declare function path(obj: any, ...keys: (string | number)[]): any;
declare type Thing = {
a: {
x: number;
y: string;
};
b: boolean;
};
declare function f1(thing: Thing): void;
declare const assignTo2: <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2];
declare function one<T>(handler: (t: T) => void): T;
declare var empty: {};
declare type Handlers<T> = {
[K in keyof T]: (t: T[K]) => void;
};
declare function on<T>(handlerHash: Handlers<T>): T;
declare var hashOfEmpty1: {};
declare var hashOfEmpty2: {
test: boolean;
};
interface Options1<Data, Computed> {
data?: Data;
computed?: Computed;
}
declare class Component1<Data, Computed> {
constructor(options: Options1<Data, Computed>);
get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K];
}
declare let c1: Component1<{
hello: string;
}, {}>;
interface Options2<Data, Computed> {
data?: Data;
computed?: Computed;
}
declare class Component2<Data, Computed> {
constructor(options: Options2<Data, Computed>);
get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K];
}
interface R {
p: number;
}
declare function f<K extends keyof R>(p: K): void;
File diff suppressed because it is too large Load Diff
@@ -47,16 +47,22 @@ type Dictionary<T> = { [x: string]: T };
>x : string
>T : T
type NumericallyIndexed<T> = { [x: number]: T };
>NumericallyIndexed : NumericallyIndexed<T>
>T : T
>x : number
>T : T
const enum E { A, B, C }
>E : E
>A : E.A
>B : E.B
>C : E.C
type K00 = keyof any; // string | number
type K00 = keyof any; // string
>K00 : string
type K01 = keyof string; // number | "toString" | "charAt" | ...
type K01 = keyof string; // "toString" | "charAt" | ...
>K01 : "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf"
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
@@ -82,11 +88,11 @@ type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
>K10 : "name" | "width" | "height" | "visible"
>Shape : Shape
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
type K11 = keyof Shape[]; // "length" | "toString" | ...
>K11 : "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>Shape : Shape
type K12 = keyof Dictionary<Shape>; // string | number
type K12 = keyof Dictionary<Shape>; // string
>K12 : string
>Dictionary : Dictionary<T>
>Shape : Shape
@@ -102,7 +108,7 @@ type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
>K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
>E : E
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
>K16 : "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K17 = keyof (Shape | Item); // "name"
@@ -115,6 +121,11 @@ type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "
>Shape : Shape
>Item : Item
type K19 = keyof NumericallyIndexed<Shape> // never
>K19 : never
>NumericallyIndexed : NumericallyIndexed<T>
>Shape : Shape
type KeyOf<T> = keyof T;
>KeyOf : keyof T
>T : T
@@ -125,7 +136,7 @@ type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
>KeyOf : keyof T
>Shape : Shape
type K21 = KeyOf<Dictionary<Shape>>; // string | number
type K21 = KeyOf<Dictionary<Shape>>; // string
>K21 : string
>KeyOf : keyof T
>Dictionary : Dictionary<T>
@@ -769,8 +780,8 @@ function f52<T>(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number)
>n : number
const x3 = obj[k];
>x3 : boolean
>obj[k] : boolean
>x3 : { [x: string]: boolean; }[keyof T]
>obj[k] : { [x: string]: boolean; }[keyof T]
>obj : { [x: string]: boolean; }
>k : keyof T
}
@@ -815,7 +826,7 @@ function f54<T>(obj: T, key: keyof T) {
>T : T
for (let s in obj[key]) {
>s : string
>s : keyof T[keyof T]
>obj[key] : T[keyof T]
>obj : T
>key : keyof T
@@ -840,7 +851,7 @@ function f55<T, K extends keyof T>(obj: T, key: K) {
>K : K
for (let s in obj[key]) {
>s : string
>s : keyof T[K]
>obj[key] : T[K]
>obj : T
>key : K
@@ -877,6 +888,264 @@ function f60<T>(source: T, target: T) {
}
}
function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
>f70 : (func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) => void
>func : <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void
>T : T
>U : U
>k1 : keyof (T | U)
>T : T
>U : U
>k2 : keyof (T & U)
>T : T
>U : U
func<{ a: any, b: any }, { a: any, c: any }>('a', 'a');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'a') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void
>a : any
>b : any
>a : any
>c : any
>'a' : "a"
>'a' : "a"
func<{ a: any, b: any }, { a: any, c: any }>('a', 'b');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'b') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void
>a : any
>b : any
>a : any
>c : any
>'a' : "a"
>'b' : "b"
func<{ a: any, b: any }, { a: any, c: any }>('a', 'c');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'c') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void
>a : any
>b : any
>a : any
>c : any
>'a' : "a"
>'c' : "c"
}
function f71(func: <T, U>(x: T, y: U) => Partial<T & U>) {
>f71 : (func: <T, U>(x: T, y: U) => Partial<T & U>) => void
>func : <T, U>(x: T, y: U) => Partial<T & U>
>T : T
>U : U
>x : T
>T : T
>y : U
>U : U
>Partial : Partial<T>
>T : T
>U : U
let x = func({ a: 1, b: "hello" }, { c: true });
>x : Partial<{ a: number; b: string; } & { c: boolean; }>
>func({ a: 1, b: "hello" }, { c: true }) : Partial<{ a: number; b: string; } & { c: boolean; }>
>func : <T, U>(x: T, y: U) => Partial<T & U>
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
x.a; // number | undefined
>x.a : number | undefined
>x : Partial<{ a: number; b: string; } & { c: boolean; }>
>a : number | undefined
x.b; // string | undefined
>x.b : string | undefined
>x : Partial<{ a: number; b: string; } & { c: boolean; }>
>b : string | undefined
x.c; // boolean | undefined
>x.c : boolean | undefined
>x : Partial<{ a: number; b: string; } & { c: boolean; }>
>c : boolean | undefined
}
function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]) {
>f72 : (func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]) => void
>func : <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]
>T : T
>U : U
>K : K
>T : T
>U : U
>x : T
>T : T
>y : U
>U : U
>k : K
>K : K
>T : T
>U : U
>K : K
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
>a : number
>func({ a: 1, b: "hello" }, { c: true }, 'a') : number
>func : <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'a' : "a"
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
>b : string
>func({ a: 1, b: "hello" }, { c: true }, 'b') : string
>func : <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'b' : "b"
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
>c : boolean
>func({ a: 1, b: "hello" }, { c: true }, 'c') : boolean
>func : <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'c' : "c"
}
function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]) {
>f73 : (func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]) => void
>func : <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]
>T : T
>U : U
>K : K
>T : T
>U : U
>x : T
>T : T
>y : U
>U : U
>k : K
>K : K
>T : T
>U : U
>K : K
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
>a : number
>func({ a: 1, b: "hello" }, { c: true }, 'a') : number
>func : <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'a' : "a"
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
>b : string
>func({ a: 1, b: "hello" }, { c: true }, 'b') : string
>func : <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'b' : "b"
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
>c : boolean
>func({ a: 1, b: "hello" }, { c: true }, 'c') : boolean
>func : <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ c: true } : { c: true; }
>c : boolean
>true : true
>'c' : "c"
}
function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) {
>f74 : (func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) => void
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>T : T
>U : U
>K : K
>T : T
>U : U
>x : T
>T : T
>y : U
>U : U
>k : K
>K : K
>T : T
>U : U
>K : K
let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number
>a : number
>func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a') : number
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ a: 2, b: true } : { a: number; b: true; }
>a : number
>2 : 2
>b : boolean
>true : true
>'a' : "a"
let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean
>b : string | boolean
>func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b') : string | boolean
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"hello" : "hello"
>{ a: 2, b: true } : { a: number; b: true; }
>a : number
>2 : 2
>b : boolean
>true : true
>'b' : "b"
}
// Repros from #12011
class Base {
@@ -970,3 +1239,351 @@ class OtherPerson {
>"parts" : "parts"
}
}
// Modified repro from #12544
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>obj : T
>T : T
>key1 : K1
>K1 : K1
>T : T
>K1 : K1
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>obj : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
>T : T
>K1 : K1
>K2 : K2
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>K3 : K3
>T : T
>K1 : K1
>K2 : K2
>obj : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
>key3 : K3
>K3 : K3
>T : T
>K1 : K1
>K2 : K2
>K3 : K3
function path(obj: any, ...keys: (string | number)[]): any;
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>obj : any
>keys : (string | number)[]
function path(obj: any, ...keys: (string | number)[]): any {
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>obj : any
>keys : (string | number)[]
let result = obj;
>result : any
>obj : any
for (let k of keys) {
>k : string | number
>keys : (string | number)[]
result = result[k];
>result = result[k] : any
>result : any
>result[k] : any
>result : any
>k : string | number
}
return result;
>result : any
}
type Thing = {
>Thing : Thing
a: { x: number, y: string },
>a : { x: number; y: string; }
>x : number
>y : string
b: boolean
>b : boolean
};
function f1(thing: Thing) {
>f1 : (thing: Thing) => void
>thing : Thing
>Thing : Thing
let x1 = path(thing, 'a'); // { x: number, y: string }
>x1 : { x: number; y: string; }
>path(thing, 'a') : { x: number; y: string; }
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'a' : "a"
let x2 = path(thing, 'a', 'y'); // string
>x2 : string
>path(thing, 'a', 'y') : string
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'a' : "a"
>'y' : "y"
let x3 = path(thing, 'b'); // boolean
>x3 : boolean
>path(thing, 'b') : boolean
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'b' : "b"
let x4 = path(thing, ...['a', 'x']); // any
>x4 : any
>path(thing, ...['a', 'x']) : any
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>...['a', 'x'] : string
>['a', 'x'] : string[]
>'a' : "a"
>'x' : "x"
}
// Repro from comment in #12114
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
>assignTo2 : <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2]
><T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => object[key1][key2] = value : <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2]
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>object : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
(value: T[K1][K2]) => object[key1][key2] = value;
>(value: T[K1][K2]) => object[key1][key2] = value : (value: T[K1][K2]) => T[K1][K2]
>value : T[K1][K2]
>T : T
>K1 : K1
>K2 : K2
>object[key1][key2] = value : T[K1][K2]
>object[key1][key2] : T[K1][K2]
>object[key1] : T[K1]
>object : T
>key1 : K1
>key2 : K2
>value : T[K1][K2]
// Modified repro from #12573
declare function one<T>(handler: (t: T) => void): T
>one : <T>(handler: (t: T) => void) => T
>T : T
>handler : (t: T) => void
>t : T
>T : T
>T : T
var empty = one(() => {}) // inferred as {}, expected
>empty : {}
>one(() => {}) : {}
>one : <T>(handler: (t: T) => void) => T
>() => {} : () => void
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
>Handlers : Handlers<T>
>T : T
>K : K
>T : T
>t : T[K]
>T : T
>K : K
declare function on<T>(handlerHash: Handlers<T>): T
>on : <T>(handlerHash: Handlers<T>) => T
>T : T
>handlerHash : Handlers<T>
>Handlers : Handlers<T>
>T : T
>T : T
var hashOfEmpty1 = on({ test: () => {} }); // {}
>hashOfEmpty1 : {}
>on({ test: () => {} }) : {}
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: () => {} } : { test: () => void; }
>test : () => void
>() => {} : () => void
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
>hashOfEmpty2 : { test: boolean; }
>on({ test: (x: boolean) => {} }) : { test: boolean; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: (x: boolean) => {} } : { test: (x: boolean) => void; }
>test : (x: boolean) => void
>(x: boolean) => {} : (x: boolean) => void
>x : boolean
// Repro from #12624
interface Options1<Data, Computed> {
>Options1 : Options1<Data, Computed>
>Data : Data
>Computed : Computed
data?: Data
>data : Data | undefined
>Data : Data
computed?: Computed;
>computed : Computed | undefined
>Computed : Computed
}
declare class Component1<Data, Computed> {
>Component1 : Component1<Data, Computed>
>Data : Data
>Computed : Computed
constructor(options: Options1<Data, Computed>);
>options : Options1<Data, Computed>
>Options1 : Options1<Data, Computed>
>Data : Data
>Computed : Computed
get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K];
>get : <K extends keyof (Data & Computed)>(key: K) => (Data & Computed)[K]
>K : K
>Data : Data
>Computed : Computed
>key : K
>K : K
>Data : Data
>Computed : Computed
>K : K
}
let c1 = new Component1({
>c1 : Component1<{ hello: string; }, {}>
>new Component1({ data: { hello: "" }}) : Component1<{ hello: string; }, {}>
>Component1 : typeof Component1
>{ data: { hello: "" }} : { data: { hello: string; }; }
data: {
>data : { hello: string; }
>{ hello: "" } : { hello: string; }
hello: ""
>hello : string
>"" : ""
}
});
c1.get("hello");
>c1.get("hello") : string
>c1.get : <K extends "hello">(key: K) => ({ hello: string; } & {})[K]
>c1 : Component1<{ hello: string; }, {}>
>get : <K extends "hello">(key: K) => ({ hello: string; } & {})[K]
>"hello" : "hello"
// Repro from #12625
interface Options2<Data, Computed> {
>Options2 : Options2<Data, Computed>
>Data : Data
>Computed : Computed
data?: Data
>data : Data | undefined
>Data : Data
computed?: Computed;
>computed : Computed | undefined
>Computed : Computed
}
declare class Component2<Data, Computed> {
>Component2 : Component2<Data, Computed>
>Data : Data
>Computed : Computed
constructor(options: Options2<Data, Computed>);
>options : Options2<Data, Computed>
>Options2 : Options2<Data, Computed>
>Data : Data
>Computed : Computed
get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K];
>get : <K extends keyof Data | keyof Computed>(key: K) => (Data & Computed)[K]
>K : K
>Data : Data
>Computed : Computed
>key : K
>K : K
>Data : Data
>Computed : Computed
>K : K
}
// Repro from #12641
interface R {
>R : R
p: number;
>p : number
}
function f<K extends keyof R>(p: K) {
>f : <K extends "p">(p: K) => void
>K : K
>R : R
>p : K
>K : K
let a: any;
>a : any
a[p].add; // any
>a[p].add : any
>a[p] : any
>a : any
>p : K
>add : any
}
@@ -21,9 +21,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(64,33): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(66,24): error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(67,24): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(72,5): error TS2536: Type 'keyof (T & U)' cannot be used to index type 'T | U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error TS2322: Type 'T | U' is not assignable to type 'T & U'.
Type 'T' is not assignable to type 'T & U'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (21 errors) ====
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (24 errors) ====
class Shape {
name: string;
width: number;
@@ -135,4 +140,23 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(67,24): error
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
!!! error TS2345: Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
o1[k1];
o1[k2]; // Error
~~~~~~
!!! error TS2536: Type 'keyof (T & U)' cannot be used to index type 'T | U'.
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
~~
!!! error TS2322: Type 'T | U' is not assignable to type 'T & U'.
!!! error TS2322: Type 'T' is not assignable to type 'T & U'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
k1 = k2; // Error
~~
!!! error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'.
k2 = k1;
}
@@ -66,6 +66,17 @@ function f10(shape: Shape) {
setProperty(shape, "name", "rectangle");
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
o1[k1];
o1[k2]; // Error
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
k1 = k2; // Error
k2 = k1;
}
//// [keyofAndIndexedAccessErrors.js]
@@ -88,3 +99,13 @@ function f10(shape) {
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}
function f20(k1, k2, o1, o2) {
o1[k1];
o1[k2]; // Error
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
k1 = k2; // Error
k2 = k1;
}
@@ -16,13 +16,19 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(38,24): error TS2344: T
Type 'T' is not assignable to type '"visible"'.
Type 'string | number' is not assignable to type '"visible"'.
Type 'string' is not assignable to type '"visible"'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(61,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(62,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(62,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(76,45): error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type 'Readonly<{ x: number; y: number; }>'.
Property 'y' is missing in type '{ x: number; }'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(78,59): error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Readonly<{ x: number; y: number; }>'.
Object literal may only specify known properties, and 'z' does not exist in type 'Readonly<{ x: number; y: number; }>'.
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(84,58): error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (14 errors) ====
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (17 errors) ====
interface Shape {
name: string;
@@ -112,13 +118,13 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Su
var x: { [P in keyof T]: T[P] };
var x: { [P in keyof T]?: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'.
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'.
var x: { readonly [P in keyof T]: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'.
var x: { readonly [P in keyof T]?: T[P] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'.
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'.
}
function f12<T>() {
@@ -126,4 +132,30 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Su
var x: { [P in keyof T]: T[P][] }; // Error
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'.
}
// Check that inferences to mapped types are secondary
declare function objAndReadonly<T>(primary: T, secondary: Readonly<T>): T;
declare function objAndPartial<T>(primary: T, secondary: Partial<T>): T;
function f20() {
let x1 = objAndReadonly({ x: 0, y: 0 }, { x: 1 }); // Error
~~~~~~~~
!!! error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type 'Readonly<{ x: number; y: number; }>'.
!!! error TS2345: Property 'y' is missing in type '{ x: number; }'.
let x2 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1 });
let x3 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
~~~~
!!! error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Readonly<{ x: number; y: number; }>'.
!!! error TS2345: Object literal may only specify known properties, and 'z' does not exist in type 'Readonly<{ x: number; y: number; }>'.
}
function f21() {
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
~~~~
!!! error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
!!! error TS2345: Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
}
@@ -66,6 +66,23 @@ function f11<T>() {
function f12<T>() {
var x: { [P in keyof T]: T[P] };
var x: { [P in keyof T]: T[P][] }; // Error
}
// Check that inferences to mapped types are secondary
declare function objAndReadonly<T>(primary: T, secondary: Readonly<T>): T;
declare function objAndPartial<T>(primary: T, secondary: Partial<T>): T;
function f20() {
let x1 = objAndReadonly({ x: 0, y: 0 }, { x: 1 }); // Error
let x2 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1 });
let x3 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
}
function f21() {
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
}
//// [mappedTypeErrors.js]
@@ -97,6 +114,16 @@ function f12() {
var x;
var x; // Error
}
function f20() {
var x1 = objAndReadonly({ x: 0, y: 0 }, { x: 1 }); // Error
var x2 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1 });
var x3 = objAndReadonly({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
}
function f21() {
var x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
var x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
var x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
}
//// [mappedTypeErrors.d.ts]
@@ -137,3 +164,7 @@ declare function f4<T extends keyof Named>(x: T): void;
declare function f10<T>(): void;
declare function f11<T>(): void;
declare function f12<T>(): void;
declare function objAndReadonly<T>(primary: T, secondary: Readonly<T>): T;
declare function objAndPartial<T>(primary: T, secondary: Partial<T>): T;
declare function f20(): void;
declare function f21(): void;
@@ -0,0 +1,145 @@
//// [mappedTypeModifiers.ts]
type T = { a: number, b: string };
type TU = { a: number | undefined, b: string | undefined };
type TP = { a?: number, b?: string };
type TR = { readonly a: number, readonly b: string };
type TPR = { readonly a?: number, readonly b?: string };
// Validate they all have the same keys
var v00: "a" | "b";
var v00: keyof T;
var v00: keyof TU;
var v00: keyof TP;
var v00: keyof TR;
var v00: keyof TPR;
// Validate that non-isomorphic mapped types strip modifiers
var v01: T;
var v01: Pick<TR, keyof T>;
var v01: Pick<Readonly<T>, keyof T>;
// Validate that non-isomorphic mapped types strip modifiers
var v02: TU;
var v02: Pick<TP, keyof T>;
var v02: Pick<TPR, keyof T>;
var v02: Pick<Partial<T>, keyof T>;
var v02: Pick<Partial<Readonly<T>>, keyof T>;
// Validate that isomorphic mapped types preserve optional modifier
var v03: TP;
var v03: Partial<T>;
// Validate that isomorphic mapped types preserve readonly modifier
var v04: TR;
var v04: Readonly<T>;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05: TPR;
var v05: Partial<TR>;
var v05: Readonly<TP>;
var v05: Partial<Readonly<T>>;
var v05: Readonly<Partial<T>>;
type Boxified<T> = { [P in keyof T]: { x: T[P] } };
type B = { a: { x: number }, b: { x: string } };
type BU = { a: { x: number } | undefined, b: { x: string } | undefined };
type BP = { a?: { x: number }, b?: { x: string } };
type BR = { readonly a: { x: number }, readonly b: { x: string } };
type BPR = { readonly a?: { x: number }, readonly b?: { x: string } };
// Validate they all have the same keys
var b00: "a" | "b";
var b00: keyof B;
var b00: keyof BU;
var b00: keyof BP;
var b00: keyof BR;
var b00: keyof BPR;
// Validate that non-isomorphic mapped types strip modifiers
var b01: B;
var b01: Pick<BR, keyof B>;
var b01: Pick<Readonly<BR>, keyof B>;
// Validate that non-isomorphic mapped types strip modifiers
var b02: BU;
var b02: Pick<BP, keyof B>;
var b02: Pick<BPR, keyof B>;
var b02: Pick<Partial<B>, keyof B>;
var b02: Pick<Partial<Readonly<B>>, keyof B>;
// Validate that isomorphic mapped types preserve optional modifier
var b03: BP;
var b03: Partial<B>;
// Validate that isomorphic mapped types preserve readonly modifier
var b04: BR;
var b04: Readonly<B>;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05: BPR;
var b05: Partial<BR>;
var b05: Readonly<BP>;
var b05: Partial<Readonly<B>>;
var b05: Readonly<Partial<B>>;
//// [mappedTypeModifiers.js]
// Validate they all have the same keys
var v00;
var v00;
var v00;
var v00;
var v00;
var v00;
// Validate that non-isomorphic mapped types strip modifiers
var v01;
var v01;
var v01;
// Validate that non-isomorphic mapped types strip modifiers
var v02;
var v02;
var v02;
var v02;
var v02;
// Validate that isomorphic mapped types preserve optional modifier
var v03;
var v03;
// Validate that isomorphic mapped types preserve readonly modifier
var v04;
var v04;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05;
var v05;
var v05;
var v05;
var v05;
// Validate they all have the same keys
var b00;
var b00;
var b00;
var b00;
var b00;
var b00;
// Validate that non-isomorphic mapped types strip modifiers
var b01;
var b01;
var b01;
// Validate that non-isomorphic mapped types strip modifiers
var b02;
var b02;
var b02;
var b02;
var b02;
// Validate that isomorphic mapped types preserve optional modifier
var b03;
var b03;
// Validate that isomorphic mapped types preserve readonly modifier
var b04;
var b04;
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05;
var b05;
var b05;
var b05;
var b05;
@@ -0,0 +1,313 @@
=== tests/cases/conformance/types/mapped/mappedTypeModifiers.ts ===
type T = { a: number, b: string };
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 1, 10))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 1, 21))
type TU = { a: number | undefined, b: string | undefined };
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 2, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 2, 34))
type TP = { a?: number, b?: string };
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 3, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 3, 23))
type TR = { readonly a: number, readonly b: string };
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 4, 11))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 4, 31))
type TPR = { readonly a?: number, readonly b?: string };
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 5, 12))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 5, 33))
// Validate they all have the same keys
var v00: "a" | "b";
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
var v00: keyof T;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v00: keyof TU;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
var v00: keyof TP;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v00: keyof TR;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v00: keyof TPR;
>v00 : Symbol(v00, Decl(mappedTypeModifiers.ts, 8, 3), Decl(mappedTypeModifiers.ts, 9, 3), Decl(mappedTypeModifiers.ts, 10, 3), Decl(mappedTypeModifiers.ts, 11, 3), Decl(mappedTypeModifiers.ts, 12, 3), Decl(mappedTypeModifiers.ts, 13, 3))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
// Validate that non-isomorphic mapped types strip modifiers
var v01: T;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v01: Pick<TR, keyof T>;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v01: Pick<Readonly<T>, keyof T>;
>v01 : Symbol(v01, Decl(mappedTypeModifiers.ts, 16, 3), Decl(mappedTypeModifiers.ts, 17, 3), Decl(mappedTypeModifiers.ts, 18, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that non-isomorphic mapped types strip modifiers
var v02: TU;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>TU : Symbol(TU, Decl(mappedTypeModifiers.ts, 1, 34))
var v02: Pick<TP, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<TPR, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<Partial<T>, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v02: Pick<Partial<Readonly<T>>, keyof T>;
>v02 : Symbol(v02, Decl(mappedTypeModifiers.ts, 21, 3), Decl(mappedTypeModifiers.ts, 22, 3), Decl(mappedTypeModifiers.ts, 23, 3), Decl(mappedTypeModifiers.ts, 24, 3), Decl(mappedTypeModifiers.ts, 25, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve optional modifier
var v03: TP;
>v03 : Symbol(v03, Decl(mappedTypeModifiers.ts, 28, 3), Decl(mappedTypeModifiers.ts, 29, 3))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v03: Partial<T>;
>v03 : Symbol(v03, Decl(mappedTypeModifiers.ts, 28, 3), Decl(mappedTypeModifiers.ts, 29, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve readonly modifier
var v04: TR;
>v04 : Symbol(v04, Decl(mappedTypeModifiers.ts, 32, 3), Decl(mappedTypeModifiers.ts, 33, 3))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v04: Readonly<T>;
>v04 : Symbol(v04, Decl(mappedTypeModifiers.ts, 32, 3), Decl(mappedTypeModifiers.ts, 33, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05: TPR;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>TPR : Symbol(TPR, Decl(mappedTypeModifiers.ts, 4, 53))
var v05: Partial<TR>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>TR : Symbol(TR, Decl(mappedTypeModifiers.ts, 3, 37))
var v05: Readonly<TP>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>TP : Symbol(TP, Decl(mappedTypeModifiers.ts, 2, 59))
var v05: Partial<Readonly<T>>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
var v05: Readonly<Partial<T>>;
>v05 : Symbol(v05, Decl(mappedTypeModifiers.ts, 36, 3), Decl(mappedTypeModifiers.ts, 37, 3), Decl(mappedTypeModifiers.ts, 38, 3), Decl(mappedTypeModifiers.ts, 39, 3), Decl(mappedTypeModifiers.ts, 40, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 0, 0))
type Boxified<T> = { [P in keyof T]: { x: T[P] } };
>Boxified : Symbol(Boxified, Decl(mappedTypeModifiers.ts, 40, 30))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>P : Symbol(P, Decl(mappedTypeModifiers.ts, 42, 22))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 42, 38))
>T : Symbol(T, Decl(mappedTypeModifiers.ts, 42, 14))
>P : Symbol(P, Decl(mappedTypeModifiers.ts, 42, 22))
type B = { a: { x: number }, b: { x: string } };
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 44, 10))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 44, 15))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 44, 28))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 44, 33))
type BU = { a: { x: number } | undefined, b: { x: string } | undefined };
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 45, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 45, 16))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 45, 41))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 45, 46))
type BP = { a?: { x: number }, b?: { x: string } };
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 46, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 46, 17))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 46, 30))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 46, 36))
type BR = { readonly a: { x: number }, readonly b: { x: string } };
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 47, 11))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 47, 25))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 47, 38))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 47, 52))
type BPR = { readonly a?: { x: number }, readonly b?: { x: string } };
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
>a : Symbol(a, Decl(mappedTypeModifiers.ts, 48, 12))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 48, 27))
>b : Symbol(b, Decl(mappedTypeModifiers.ts, 48, 40))
>x : Symbol(x, Decl(mappedTypeModifiers.ts, 48, 55))
// Validate they all have the same keys
var b00: "a" | "b";
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
var b00: keyof B;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b00: keyof BU;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
var b00: keyof BP;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b00: keyof BR;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b00: keyof BPR;
>b00 : Symbol(b00, Decl(mappedTypeModifiers.ts, 51, 3), Decl(mappedTypeModifiers.ts, 52, 3), Decl(mappedTypeModifiers.ts, 53, 3), Decl(mappedTypeModifiers.ts, 54, 3), Decl(mappedTypeModifiers.ts, 55, 3), Decl(mappedTypeModifiers.ts, 56, 3))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
// Validate that non-isomorphic mapped types strip modifiers
var b01: B;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b01: Pick<BR, keyof B>;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b01: Pick<Readonly<BR>, keyof B>;
>b01 : Symbol(b01, Decl(mappedTypeModifiers.ts, 59, 3), Decl(mappedTypeModifiers.ts, 60, 3), Decl(mappedTypeModifiers.ts, 61, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that non-isomorphic mapped types strip modifiers
var b02: BU;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>BU : Symbol(BU, Decl(mappedTypeModifiers.ts, 44, 48))
var b02: Pick<BP, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<BPR, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<Partial<B>, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b02: Pick<Partial<Readonly<B>>, keyof B>;
>b02 : Symbol(b02, Decl(mappedTypeModifiers.ts, 64, 3), Decl(mappedTypeModifiers.ts, 65, 3), Decl(mappedTypeModifiers.ts, 66, 3), Decl(mappedTypeModifiers.ts, 67, 3), Decl(mappedTypeModifiers.ts, 68, 3))
>Pick : Symbol(Pick, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve optional modifier
var b03: BP;
>b03 : Symbol(b03, Decl(mappedTypeModifiers.ts, 71, 3), Decl(mappedTypeModifiers.ts, 72, 3))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b03: Partial<B>;
>b03 : Symbol(b03, Decl(mappedTypeModifiers.ts, 71, 3), Decl(mappedTypeModifiers.ts, 72, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve readonly modifier
var b04: BR;
>b04 : Symbol(b04, Decl(mappedTypeModifiers.ts, 75, 3), Decl(mappedTypeModifiers.ts, 76, 3))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b04: Readonly<B>;
>b04 : Symbol(b04, Decl(mappedTypeModifiers.ts, 75, 3), Decl(mappedTypeModifiers.ts, 76, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05: BPR;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>BPR : Symbol(BPR, Decl(mappedTypeModifiers.ts, 47, 67))
var b05: Partial<BR>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>BR : Symbol(BR, Decl(mappedTypeModifiers.ts, 46, 51))
var b05: Readonly<BP>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>BP : Symbol(BP, Decl(mappedTypeModifiers.ts, 45, 73))
var b05: Partial<Readonly<B>>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
var b05: Readonly<Partial<B>>;
>b05 : Symbol(b05, Decl(mappedTypeModifiers.ts, 79, 3), Decl(mappedTypeModifiers.ts, 80, 3), Decl(mappedTypeModifiers.ts, 81, 3), Decl(mappedTypeModifiers.ts, 82, 3), Decl(mappedTypeModifiers.ts, 83, 3))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>B : Symbol(B, Decl(mappedTypeModifiers.ts, 42, 51))
@@ -0,0 +1,313 @@
=== tests/cases/conformance/types/mapped/mappedTypeModifiers.ts ===
type T = { a: number, b: string };
>T : T
>a : number
>b : string
type TU = { a: number | undefined, b: string | undefined };
>TU : TU
>a : number | undefined
>b : string | undefined
type TP = { a?: number, b?: string };
>TP : TP
>a : number | undefined
>b : string | undefined
type TR = { readonly a: number, readonly b: string };
>TR : TR
>a : number
>b : string
type TPR = { readonly a?: number, readonly b?: string };
>TPR : TPR
>a : number | undefined
>b : string | undefined
// Validate they all have the same keys
var v00: "a" | "b";
>v00 : "a" | "b"
var v00: keyof T;
>v00 : "a" | "b"
>T : T
var v00: keyof TU;
>v00 : "a" | "b"
>TU : TU
var v00: keyof TP;
>v00 : "a" | "b"
>TP : TP
var v00: keyof TR;
>v00 : "a" | "b"
>TR : TR
var v00: keyof TPR;
>v00 : "a" | "b"
>TPR : TPR
// Validate that non-isomorphic mapped types strip modifiers
var v01: T;
>v01 : T
>T : T
var v01: Pick<TR, keyof T>;
>v01 : T
>Pick : Pick<T, K>
>TR : TR
>T : T
var v01: Pick<Readonly<T>, keyof T>;
>v01 : T
>Pick : Pick<T, K>
>Readonly : Readonly<T>
>T : T
>T : T
// Validate that non-isomorphic mapped types strip modifiers
var v02: TU;
>v02 : TU
>TU : TU
var v02: Pick<TP, keyof T>;
>v02 : TU
>Pick : Pick<T, K>
>TP : TP
>T : T
var v02: Pick<TPR, keyof T>;
>v02 : TU
>Pick : Pick<T, K>
>TPR : TPR
>T : T
var v02: Pick<Partial<T>, keyof T>;
>v02 : TU
>Pick : Pick<T, K>
>Partial : Partial<T>
>T : T
>T : T
var v02: Pick<Partial<Readonly<T>>, keyof T>;
>v02 : TU
>Pick : Pick<T, K>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>T : T
// Validate that isomorphic mapped types preserve optional modifier
var v03: TP;
>v03 : TP
>TP : TP
var v03: Partial<T>;
>v03 : TP
>Partial : Partial<T>
>T : T
// Validate that isomorphic mapped types preserve readonly modifier
var v04: TR;
>v04 : TR
>TR : TR
var v04: Readonly<T>;
>v04 : TR
>Readonly : Readonly<T>
>T : T
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var v05: TPR;
>v05 : TPR
>TPR : TPR
var v05: Partial<TR>;
>v05 : TPR
>Partial : Partial<T>
>TR : TR
var v05: Readonly<TP>;
>v05 : TPR
>Readonly : Readonly<T>
>TP : TP
var v05: Partial<Readonly<T>>;
>v05 : TPR
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
var v05: Readonly<Partial<T>>;
>v05 : TPR
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
type Boxified<T> = { [P in keyof T]: { x: T[P] } };
>Boxified : Boxified<T>
>T : T
>P : P
>T : T
>x : T[P]
>T : T
>P : P
type B = { a: { x: number }, b: { x: string } };
>B : B
>a : { x: number; }
>x : number
>b : { x: string; }
>x : string
type BU = { a: { x: number } | undefined, b: { x: string } | undefined };
>BU : BU
>a : { x: number; } | undefined
>x : number
>b : { x: string; } | undefined
>x : string
type BP = { a?: { x: number }, b?: { x: string } };
>BP : BP
>a : { x: number; } | undefined
>x : number
>b : { x: string; } | undefined
>x : string
type BR = { readonly a: { x: number }, readonly b: { x: string } };
>BR : BR
>a : { x: number; }
>x : number
>b : { x: string; }
>x : string
type BPR = { readonly a?: { x: number }, readonly b?: { x: string } };
>BPR : BPR
>a : { x: number; } | undefined
>x : number
>b : { x: string; } | undefined
>x : string
// Validate they all have the same keys
var b00: "a" | "b";
>b00 : "a" | "b"
var b00: keyof B;
>b00 : "a" | "b"
>B : B
var b00: keyof BU;
>b00 : "a" | "b"
>BU : BU
var b00: keyof BP;
>b00 : "a" | "b"
>BP : BP
var b00: keyof BR;
>b00 : "a" | "b"
>BR : BR
var b00: keyof BPR;
>b00 : "a" | "b"
>BPR : BPR
// Validate that non-isomorphic mapped types strip modifiers
var b01: B;
>b01 : B
>B : B
var b01: Pick<BR, keyof B>;
>b01 : B
>Pick : Pick<T, K>
>BR : BR
>B : B
var b01: Pick<Readonly<BR>, keyof B>;
>b01 : B
>Pick : Pick<T, K>
>Readonly : Readonly<T>
>BR : BR
>B : B
// Validate that non-isomorphic mapped types strip modifiers
var b02: BU;
>b02 : BU
>BU : BU
var b02: Pick<BP, keyof B>;
>b02 : BU
>Pick : Pick<T, K>
>BP : BP
>B : B
var b02: Pick<BPR, keyof B>;
>b02 : BU
>Pick : Pick<T, K>
>BPR : BPR
>B : B
var b02: Pick<Partial<B>, keyof B>;
>b02 : BU
>Pick : Pick<T, K>
>Partial : Partial<T>
>B : B
>B : B
var b02: Pick<Partial<Readonly<B>>, keyof B>;
>b02 : BU
>Pick : Pick<T, K>
>Partial : Partial<T>
>Readonly : Readonly<T>
>B : B
>B : B
// Validate that isomorphic mapped types preserve optional modifier
var b03: BP;
>b03 : BP
>BP : BP
var b03: Partial<B>;
>b03 : BP
>Partial : Partial<T>
>B : B
// Validate that isomorphic mapped types preserve readonly modifier
var b04: BR;
>b04 : BR
>BR : BR
var b04: Readonly<B>;
>b04 : BR
>Readonly : Readonly<T>
>B : B
// Validate that isomorphic mapped types preserve both partial and readonly modifiers
var b05: BPR;
>b05 : BPR
>BPR : BPR
var b05: Partial<BR>;
>b05 : BPR
>Partial : Partial<T>
>BR : BR
var b05: Readonly<BP>;
>b05 : BPR
>Readonly : Readonly<T>
>BP : BP
var b05: Partial<Readonly<B>>;
>b05 : BPR
>Partial : Partial<T>
>Readonly : Readonly<T>
>B : B
var b05: Readonly<Partial<B>>;
>b05 : BPR
>Readonly : Readonly<T>
>Partial : Partial<T>
>B : B
+7 -1
View File
@@ -36,6 +36,8 @@ let computed = 'b';
let computed2 = 'a';
var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o);
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
//// [objectRest.js]
@@ -43,7 +45,7 @@ var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
@@ -76,4 +78,8 @@ let computed = 'b';
let computed2 = 'a';
var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]);
(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""]));
var noContextualType = (_a) => {
var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]);
return aNumber + notEmptyObject['anythingGoes'];
};
var _d, _f, _j, _k;
@@ -169,3 +169,10 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51))
>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51))
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
>noContextualType : Symbol(noContextualType, Decl(objectRest.ts, 38, 3))
>aNumber : Symbol(aNumber, Decl(objectRest.ts, 38, 25))
>notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 38, 39))
>aNumber : Symbol(aNumber, Decl(objectRest.ts, 38, 25))
>notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 38, 39))
@@ -195,3 +195,15 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
>o : { a: number; b: string; }
>o : { a: number; b: string; }
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
>noContextualType : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any
>({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'] : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any
>aNumber : number
>12 : 12
>notEmptyObject : { [x: string]: any; }
>aNumber + notEmptyObject['anythingGoes'] : any
>aNumber : number
>notEmptyObject['anythingGoes'] : any
>notEmptyObject : { [x: string]: any; }
>'anythingGoes' : "anythingGoes"
@@ -19,7 +19,7 @@ var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
+1 -1
View File
@@ -27,7 +27,7 @@ var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
@@ -3,11 +3,14 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(6,10): error TS2322: Ty
Types of property 'a' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/rest/objectRestNegative.ts(9,31): error TS2462: A rest element must be last in a destructuring pattern
tests/cases/conformance/types/rest/objectRestNegative.ts(11,30): error TS7008: Member 'x' implicitly has an 'any' type.
tests/cases/conformance/types/rest/objectRestNegative.ts(11,33): error TS7008: Member 'y' implicitly has an 'any' type.
tests/cases/conformance/types/rest/objectRestNegative.ts(12,17): error TS2700: Rest types may only be created from object types.
tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: The target of an object rest assignment must be a variable or a property access.
tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'.
==== tests/cases/conformance/types/rest/objectRestNegative.ts (5 errors) ====
==== tests/cases/conformance/types/rest/objectRestNegative.ts (8 errors) ====
let o = { a: 1, b: 'no' };
var { ...mustBeLast, a } = o;
~~~~~~~~~~
@@ -27,6 +30,10 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: Th
!!! error TS2462: A rest element must be last in a destructuring pattern
}
function generic<T extends { x, y }>(t: T) {
~~
!!! error TS7008: Member 'x' implicitly has an 'any' type.
~
!!! error TS7008: Member 'y' implicitly has an 'any' type.
let { x, ...rest } = t;
~~~~
!!! error TS2700: Rest types may only be created from object types.
@@ -37,4 +44,8 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: Th
({a, ...rest.b + rest.b} = o);
~~~~~~~~~~~~~~~
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
~~~~~~~~~~~~
!!! error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'.
@@ -16,6 +16,8 @@ function generic<T extends { x, y }>(t: T) {
let rest: { b: string }
({a, ...rest.b + rest.b} = o);
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
//// [objectRestNegative.js]
@@ -23,7 +25,7 @@ var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
@@ -42,3 +44,7 @@ function generic(t) {
}
var rest;
(a = o.a, o, rest.b + rest.b = __rest(o, ["a"]));
var noContextualType = function (_a) {
var _b = _a.aNumber, aNumber = _b === void 0 ? 12 : _b, notEmptyObject = __rest(_a, ["aNumber"]);
return aNumber + notEmptyObject.anythingGoes;
};
@@ -22,7 +22,7 @@ var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (typeof Object.getOwnPropertySymbols === "function")
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
@@ -7,20 +7,18 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,1): error TS2322
Property 's' is missing in type '{ b: boolean; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,36): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,53): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,20): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,24): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(34,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,20): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(39,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(44,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(48,12): error TS2339: Property 'b' does not exist on type '{}'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(54,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,14): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,20): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(56,14): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS2698: Spread types may only be created from object types.
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ====
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (15 errors) ====
let o = { a: 1, b: 'no' }
/// private propagates
@@ -66,13 +64,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS269
!!! error TS2300: Duplicate identifier 'b'.
let duplicatedSpread = { ...o, ...o }
// null, undefined and primitives are not allowed
let spreadNull = { ...null };
~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
let spreadUndefind = { ...undefined };
~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
// primitives are not allowed
let spreadNum = { ...12 };
~~~~~
!!! error TS2698: Spread types may only be created from object types.
@@ -29,9 +29,7 @@ spread = b; // error, missing 's'
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
let duplicatedSpread = { ...o, ...o }
// null, undefined and primitives are not allowed
let spreadNull = { ...null };
let spreadUndefind = { ...undefined };
// primitives are not allowed
let spreadNum = { ...12 };
let spreadSum = { ...1 + 1 };
spreadSum.toFixed(); // error, no methods from number
@@ -108,9 +106,7 @@ spread = b; // error, missing 's'
// literal repeats are not allowed, but spread repeats are fine
var duplicated = __assign({ b: 'bad' }, o, { b: 'bad' }, o2, { b: 'bad' });
var duplicatedSpread = __assign({}, o, o);
// null, undefined and primitives are not allowed
var spreadNull = __assign({}, null);
var spreadUndefind = __assign({}, undefined);
// primitives are not allowed
var spreadNum = __assign({}, 12);
var spreadSum = __assign({}, 1 + 1);
spreadSum.toFixed(); // error, no methods from number
@@ -0,0 +1,20 @@
//// [restIntersection.ts]
var intersection: { x: number, y: number } & { w: string, z: string };
var rest1: { y: number, w: string, z: string };
var {x, ...rest1 } = intersection;
//// [restIntersection.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var intersection;
var rest1;
var x = intersection.x, rest1 = __rest(intersection, ["x"]);
@@ -0,0 +1,19 @@
=== tests/cases/compiler/restIntersection.ts ===
var intersection: { x: number, y: number } & { w: string, z: string };
>intersection : Symbol(intersection, Decl(restIntersection.ts, 0, 3))
>x : Symbol(x, Decl(restIntersection.ts, 0, 19))
>y : Symbol(y, Decl(restIntersection.ts, 0, 30))
>w : Symbol(w, Decl(restIntersection.ts, 0, 46))
>z : Symbol(z, Decl(restIntersection.ts, 0, 57))
var rest1: { y: number, w: string, z: string };
>rest1 : Symbol(rest1, Decl(restIntersection.ts, 2, 3), Decl(restIntersection.ts, 3, 7))
>y : Symbol(y, Decl(restIntersection.ts, 2, 12))
>w : Symbol(w, Decl(restIntersection.ts, 2, 23))
>z : Symbol(z, Decl(restIntersection.ts, 2, 34))
var {x, ...rest1 } = intersection;
>x : Symbol(x, Decl(restIntersection.ts, 3, 5))
>rest1 : Symbol(rest1, Decl(restIntersection.ts, 2, 3), Decl(restIntersection.ts, 3, 7))
>intersection : Symbol(intersection, Decl(restIntersection.ts, 0, 3))
@@ -0,0 +1,19 @@
=== tests/cases/compiler/restIntersection.ts ===
var intersection: { x: number, y: number } & { w: string, z: string };
>intersection : { x: number; y: number; } & { w: string; z: string; }
>x : number
>y : number
>w : string
>z : string
var rest1: { y: number, w: string, z: string };
>rest1 : { y: number; w: string; z: string; }
>y : number
>w : string
>z : string
var {x, ...rest1 } = intersection;
>x : number
>rest1 : { y: number; w: string; z: string; }
>intersection : { x: number; y: number; } & { w: string; z: string; }
@@ -0,0 +1,104 @@
tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(33,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(35,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(36,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(38,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(41,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(42,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(44,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(45,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(47,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(48,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(55,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(56,13): error TS2700: Rest types may only be created from object types.
tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types may only be created from object types.
==== tests/cases/compiler/restInvalidArgumentType.ts (14 errors) ====
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var {...r1} = p1; // Error, generic type paramterre
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r2} = p2; // OK
var {...r3} = t; // Error, generic type paramter
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r4} = i; // Error, index access
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r5} = k; // Error, index
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r6} = mapped_generic; // Error, generic mapped object type
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r7} = mapped; // OK, non-generic mapped type
var {...r8} = union_generic; // Error, union with generic type parameter
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r9} = union_primitive; // Error, union with generic type parameter
~~
!!! error TS2700: Rest types may only be created from object types.
var {...r10} = intersection_generic; // Error, intersection with generic type parameter
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r11} = intersection_premitive; // Error, intersection with generic type parameter
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r12} = num; // Error
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r13} = str; // Error
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r14} = u; // OK
var {...r15} = n; // OK
var {...r16} = a; // OK
var {...r17} = literal_string; // Error
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r18} = literal_number; // Error
~~~
!!! error TS2700: Rest types may only be created from object types.
var {...r19} = e; // Error, enum
~~~
!!! error TS2700: Rest types may only be created from object types.
}
@@ -0,0 +1,115 @@
//// [restInvalidArgumentType.ts]
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var {...r1} = p1; // Error, generic type paramterre
var {...r2} = p2; // OK
var {...r3} = t; // Error, generic type paramter
var {...r4} = i; // Error, index access
var {...r5} = k; // Error, index
var {...r6} = mapped_generic; // Error, generic mapped object type
var {...r7} = mapped; // OK, non-generic mapped type
var {...r8} = union_generic; // Error, union with generic type parameter
var {...r9} = union_primitive; // Error, union with generic type parameter
var {...r10} = intersection_generic; // Error, intersection with generic type parameter
var {...r11} = intersection_premitive; // Error, intersection with generic type parameter
var {...r12} = num; // Error
var {...r13} = str; // Error
var {...r14} = u; // OK
var {...r15} = n; // OK
var {...r16} = a; // OK
var {...r17} = literal_string; // Error
var {...r18} = literal_number; // Error
var {...r19} = e; // Error, enum
}
//// [restInvalidArgumentType.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var E;
(function (E) {
E[E["v1"] = 0] = "v1";
E[E["v2"] = 1] = "v2";
})(E || (E = {}));
;
function f(p1, p2) {
var t;
var i;
var k;
var mapped_generic;
var mapped;
var union_generic;
var union_primitive;
var intersection_generic;
var intersection_premitive;
var num;
var str;
var u;
var n;
var a;
var literal_string;
var literal_number;
var e;
var r1 = __rest(p1, []); // Error, generic type paramterre
var r2 = __rest(p2, []); // OK
var r3 = __rest(t, []); // Error, generic type paramter
var r4 = __rest(i, []); // Error, index access
var r5 = __rest(k, []); // Error, index
var r6 = __rest(mapped_generic, []); // Error, generic mapped object type
var r7 = __rest(mapped, []); // OK, non-generic mapped type
var r8 = __rest(union_generic, []); // Error, union with generic type parameter
var r9 = __rest(union_primitive, []); // Error, union with generic type parameter
var r10 = __rest(intersection_generic, []); // Error, intersection with generic type parameter
var r11 = __rest(intersection_premitive, []); // Error, intersection with generic type parameter
var r12 = __rest(num, []); // Error
var r13 = __rest(str, []); // Error
var r14 = __rest(u, []); // OK
var r15 = __rest(n, []); // OK
var r16 = __rest(a, []); // OK
var r17 = __rest(literal_string, []); // Error
var r18 = __rest(literal_number, []); // Error
var r19 = __rest(e, []); // Error, enum
}
+36
View File
@@ -0,0 +1,36 @@
//// [restUnion.ts]
var union: { a: number, c: boolean } | { a: string, b: string };
var rest1: { c: boolean } | { b: string };
var {a, ...rest1 } = union;
var undefinedUnion: { n: number } | undefined;
var rest2: {};
var {n, ...rest2 } = undefinedUnion;
var nullUnion: { n: number } | null;
var rest3: {};
var {n, ...rest3 } = nullUnion;
//// [restUnion.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var union;
var rest1;
var a = union.a, rest1 = __rest(union, ["a"]);
var undefinedUnion;
var rest2;
var n = undefinedUnion.n, rest2 = __rest(undefinedUnion, ["n"]);
var nullUnion;
var rest3;
var n = nullUnion.n, rest3 = __rest(nullUnion, ["n"]);
@@ -0,0 +1,44 @@
=== tests/cases/compiler/restUnion.ts ===
var union: { a: number, c: boolean } | { a: string, b: string };
>union : Symbol(union, Decl(restUnion.ts, 0, 3))
>a : Symbol(a, Decl(restUnion.ts, 0, 12))
>c : Symbol(c, Decl(restUnion.ts, 0, 23))
>a : Symbol(a, Decl(restUnion.ts, 0, 40))
>b : Symbol(b, Decl(restUnion.ts, 0, 51))
var rest1: { c: boolean } | { b: string };
>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7))
>c : Symbol(c, Decl(restUnion.ts, 2, 12))
>b : Symbol(b, Decl(restUnion.ts, 2, 29))
var {a, ...rest1 } = union;
>a : Symbol(a, Decl(restUnion.ts, 3, 5))
>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7))
>union : Symbol(union, Decl(restUnion.ts, 0, 3))
var undefinedUnion: { n: number } | undefined;
>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3))
>n : Symbol(n, Decl(restUnion.ts, 6, 21))
var rest2: {};
>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7))
var {n, ...rest2 } = undefinedUnion;
>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5))
>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7))
>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3))
var nullUnion: { n: number } | null;
>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3))
>n : Symbol(n, Decl(restUnion.ts, 11, 16))
var rest3: {};
>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7))
var {n, ...rest3 } = nullUnion;
>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5))
>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7))
>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3))
+45
View File
@@ -0,0 +1,45 @@
=== tests/cases/compiler/restUnion.ts ===
var union: { a: number, c: boolean } | { a: string, b: string };
>union : { a: number; c: boolean; } | { a: string; b: string; }
>a : number
>c : boolean
>a : string
>b : string
var rest1: { c: boolean } | { b: string };
>rest1 : { c: boolean; } | { b: string; }
>c : boolean
>b : string
var {a, ...rest1 } = union;
>a : string | number
>rest1 : { c: boolean; } | { b: string; }
>union : { a: number; c: boolean; } | { a: string; b: string; }
var undefinedUnion: { n: number } | undefined;
>undefinedUnion : { n: number; }
>n : number
var rest2: {};
>rest2 : {}
var {n, ...rest2 } = undefinedUnion;
>n : number
>rest2 : {}
>undefinedUnion : { n: number; }
var nullUnion: { n: number } | null;
>nullUnion : { n: number; }
>n : number
>null : null
var rest3: {};
>rest3 : {}
var {n, ...rest3 } = nullUnion;
>n : number
>rest3 : {}
>nullUnion : { n: number; }
+38
View File
@@ -0,0 +1,38 @@
//// [restUnion2.ts]
declare const undefinedUnion: { n: number } | undefined;
var rest2: { n: number };
var {...rest2 } = undefinedUnion;
declare const nullUnion: { n: number } | null;
var rest3: { n: number };
var {...rest3 } = nullUnion;
declare const nullAndUndefinedUnion: null | undefined;
var rest4: { };
var {...rest4 } = nullAndUndefinedUnion;
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null;
var rest5: { n: number, s: string };
var {...rest5 } = unionWithIntersection;
//// [restUnion2.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var rest2;
var rest2 = __rest(undefinedUnion, []);
var rest3;
var rest3 = __rest(nullUnion, []);
var rest4;
var rest4 = __rest(nullAndUndefinedUnion, []);
var rest5;
var rest5 = __rest(unionWithIntersection, []);
@@ -0,0 +1,52 @@
=== tests/cases/compiler/restUnion2.ts ===
declare const undefinedUnion: { n: number } | undefined;
>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13))
>n : Symbol(n, Decl(restUnion2.ts, 1, 31))
var rest2: { n: number };
>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5))
>n : Symbol(n, Decl(restUnion2.ts, 2, 12))
var {...rest2 } = undefinedUnion;
>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5))
>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13))
declare const nullUnion: { n: number } | null;
>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13))
>n : Symbol(n, Decl(restUnion2.ts, 6, 26))
var rest3: { n: number };
>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5))
>n : Symbol(n, Decl(restUnion2.ts, 7, 12))
var {...rest3 } = nullUnion;
>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5))
>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13))
declare const nullAndUndefinedUnion: null | undefined;
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13))
var rest4: { };
>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5))
var {...rest4 } = nullAndUndefinedUnion;
>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5))
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13))
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null;
>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13))
>n : Symbol(n, Decl(restUnion2.ts, 15, 39))
>s : Symbol(s, Decl(restUnion2.ts, 15, 55))
var rest5: { n: number, s: string };
>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5))
>n : Symbol(n, Decl(restUnion2.ts, 16, 12))
>s : Symbol(s, Decl(restUnion2.ts, 16, 23))
var {...rest5 } = unionWithIntersection;
>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5))
>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13))
@@ -0,0 +1,55 @@
=== tests/cases/compiler/restUnion2.ts ===
declare const undefinedUnion: { n: number } | undefined;
>undefinedUnion : { n: number; } | undefined
>n : number
var rest2: { n: number };
>rest2 : { n: number; }
>n : number
var {...rest2 } = undefinedUnion;
>rest2 : { n: number; }
>undefinedUnion : { n: number; } | undefined
declare const nullUnion: { n: number } | null;
>nullUnion : { n: number; } | null
>n : number
>null : null
var rest3: { n: number };
>rest3 : { n: number; }
>n : number
var {...rest3 } = nullUnion;
>rest3 : { n: number; }
>nullUnion : { n: number; } | null
declare const nullAndUndefinedUnion: null | undefined;
>nullAndUndefinedUnion : null | undefined
>null : null
var rest4: { };
>rest4 : {}
var {...rest4 } = nullAndUndefinedUnion;
>rest4 : {}
>nullAndUndefinedUnion : null | undefined
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null;
>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null
>n : number
>s : string
>null : null
var rest5: { n: number, s: string };
>rest5 : { n: number; s: string; }
>n : number
>s : string
var {...rest5 } = unionWithIntersection;
>rest5 : { n: number; s: string; }
>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null
@@ -0,0 +1,23 @@
//// [spreadIntersection.ts]
var intersection: { a: number } & { b: string };
var o1: { a: number, b: string };
var o1 = { ...intersection };
var o2: { a: number, b: string, c: boolean };
var o2 = { ...intersection, c: false };
//// [spreadIntersection.js]
var __assign = (this && this.__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;
};
var intersection;
var o1;
var o1 = __assign({}, intersection);
var o2;
var o2 = __assign({}, intersection, { c: false });
@@ -0,0 +1,26 @@
=== tests/cases/compiler/spreadIntersection.ts ===
var intersection: { a: number } & { b: string };
>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3))
>a : Symbol(a, Decl(spreadIntersection.ts, 0, 19))
>b : Symbol(b, Decl(spreadIntersection.ts, 0, 35))
var o1: { a: number, b: string };
>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3))
>a : Symbol(a, Decl(spreadIntersection.ts, 2, 9))
>b : Symbol(b, Decl(spreadIntersection.ts, 2, 20))
var o1 = { ...intersection };
>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3))
>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3))
var o2: { a: number, b: string, c: boolean };
>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3))
>a : Symbol(a, Decl(spreadIntersection.ts, 5, 9))
>b : Symbol(b, Decl(spreadIntersection.ts, 5, 20))
>c : Symbol(c, Decl(spreadIntersection.ts, 5, 31))
var o2 = { ...intersection, c: false };
>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3))
>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3))
>c : Symbol(c, Decl(spreadIntersection.ts, 6, 27))
@@ -0,0 +1,29 @@
=== tests/cases/compiler/spreadIntersection.ts ===
var intersection: { a: number } & { b: string };
>intersection : { a: number; } & { b: string; }
>a : number
>b : string
var o1: { a: number, b: string };
>o1 : { a: number; b: string; }
>a : number
>b : string
var o1 = { ...intersection };
>o1 : { a: number; b: string; }
>{ ...intersection } : { a: number; b: string; }
>intersection : { a: number; } & { b: string; }
var o2: { a: number, b: string, c: boolean };
>o2 : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
var o2 = { ...intersection, c: false };
>o2 : { a: number; b: string; c: boolean; }
>{ ...intersection, c: false } : { c: boolean; a: number; b: string; }
>intersection : { a: number; } & { b: string; }
>c : boolean
>false : false
@@ -0,0 +1,104 @@
tests/cases/compiler/spreadInvalidArgumentType.ts(31,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(35,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(36,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(38,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(41,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(42,16): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(44,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(45,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(47,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(48,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(56,17): error TS2698: Spread types may only be created from object types.
tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread types may only be created from object types.
==== tests/cases/compiler/spreadInvalidArgumentType.ts (14 errors) ====
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var o1 = { ...p1 }; // Error, generic type paramterre
~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o2 = { ...p2 }; // OK
var o3 = { ...t }; // Error, generic type paramter
~~~~
!!! error TS2698: Spread types may only be created from object types.
var o4 = { ...i }; // Error, index access
~~~~
!!! error TS2698: Spread types may only be created from object types.
var o5 = { ...k }; // Error, index
~~~~
!!! error TS2698: Spread types may only be created from object types.
var o6 = { ...mapped_generic }; // Error, generic mapped object type
~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o7 = { ...mapped }; // OK, non-generic mapped type
var o8 = { ...union_generic }; // Error, union with generic type parameter
~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o9 = { ...union_primitive }; // Error, union with generic type parameter
~~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o12 = { ...num }; // Error
~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o13 = { ...str }; // Error
~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o14 = { ...u }; // OK
var o15 = { ...n }; // OK
var o16 = { ...a }; // OK
var o17 = { ...literal_string }; // Error
~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o18 = { ...literal_number }; // Error
~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var o19 = { ...e }; // Error, enum
~~~~
!!! error TS2698: Spread types may only be created from object types.
}
@@ -0,0 +1,114 @@
//// [spreadInvalidArgumentType.ts]
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var o1 = { ...p1 }; // Error, generic type paramterre
var o2 = { ...p2 }; // OK
var o3 = { ...t }; // Error, generic type paramter
var o4 = { ...i }; // Error, index access
var o5 = { ...k }; // Error, index
var o6 = { ...mapped_generic }; // Error, generic mapped object type
var o7 = { ...mapped }; // OK, non-generic mapped type
var o8 = { ...union_generic }; // Error, union with generic type parameter
var o9 = { ...union_primitive }; // Error, union with generic type parameter
var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter
var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter
var o12 = { ...num }; // Error
var o13 = { ...str }; // Error
var o14 = { ...u }; // OK
var o15 = { ...n }; // OK
var o16 = { ...a }; // OK
var o17 = { ...literal_string }; // Error
var o18 = { ...literal_number }; // Error
var o19 = { ...e }; // Error, enum
}
//// [spreadInvalidArgumentType.js]
var __assign = (this && this.__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;
};
var E;
(function (E) {
E[E["v1"] = 0] = "v1";
E[E["v2"] = 1] = "v2";
})(E || (E = {}));
;
function f(p1, p2) {
var t;
var i;
var k;
var mapped_generic;
var mapped;
var union_generic;
var union_primitive;
var intersection_generic;
var intersection_premitive;
var num;
var str;
var u;
var n;
var a;
var literal_string;
var literal_number;
var e;
var o1 = __assign({}, p1); // Error, generic type paramterre
var o2 = __assign({}, p2); // OK
var o3 = __assign({}, t); // Error, generic type paramter
var o4 = __assign({}, i); // Error, index access
var o5 = __assign({}, k); // Error, index
var o6 = __assign({}, mapped_generic); // Error, generic mapped object type
var o7 = __assign({}, mapped); // OK, non-generic mapped type
var o8 = __assign({}, union_generic); // Error, union with generic type parameter
var o9 = __assign({}, union_primitive); // Error, union with generic type parameter
var o10 = __assign({}, intersection_generic); // Error, intersection with generic type parameter
var o11 = __assign({}, intersection_premitive); // Error, intersection with generic type parameter
var o12 = __assign({}, num); // Error
var o13 = __assign({}, str); // Error
var o14 = __assign({}, u); // OK
var o15 = __assign({}, n); // OK
var o16 = __assign({}, a); // OK
var o17 = __assign({}, literal_string); // Error
var o18 = __assign({}, literal_number); // Error
var o19 = __assign({}, e); // Error, enum
}
+28
View File
@@ -0,0 +1,28 @@
//// [spreadUnion.ts]
var union: { a: number } | { b: string };
var o3: { a: number } | { b: string };
var o3 = { ...union };
var o4: { a: boolean } | { b: string , a: boolean};
var o4 = { ...union, a: false };
var o5: { a: number } | { b: string } | { a: number, b: string };
var o5 = { ...union, ...union };
//// [spreadUnion.js]
var __assign = (this && this.__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;
};
var union;
var o3;
var o3 = __assign({}, union);
var o4;
var o4 = __assign({}, union, { a: false });
var o5;
var o5 = __assign({}, union, union);
@@ -0,0 +1,38 @@
=== tests/cases/compiler/spreadUnion.ts ===
var union: { a: number } | { b: string };
>union : Symbol(union, Decl(spreadUnion.ts, 0, 3))
>a : Symbol(a, Decl(spreadUnion.ts, 0, 12))
>b : Symbol(b, Decl(spreadUnion.ts, 0, 28))
var o3: { a: number } | { b: string };
>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3))
>a : Symbol(a, Decl(spreadUnion.ts, 2, 9))
>b : Symbol(b, Decl(spreadUnion.ts, 2, 25))
var o3 = { ...union };
>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3))
>union : Symbol(union, Decl(spreadUnion.ts, 0, 3))
var o4: { a: boolean } | { b: string , a: boolean};
>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3))
>a : Symbol(a, Decl(spreadUnion.ts, 5, 9))
>b : Symbol(b, Decl(spreadUnion.ts, 5, 26))
>a : Symbol(a, Decl(spreadUnion.ts, 5, 38))
var o4 = { ...union, a: false };
>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3))
>union : Symbol(union, Decl(spreadUnion.ts, 0, 3))
>a : Symbol(a, Decl(spreadUnion.ts, 6, 21))
var o5: { a: number } | { b: string } | { a: number, b: string };
>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3))
>a : Symbol(a, Decl(spreadUnion.ts, 8, 9))
>b : Symbol(b, Decl(spreadUnion.ts, 8, 25))
>a : Symbol(a, Decl(spreadUnion.ts, 8, 41))
>b : Symbol(b, Decl(spreadUnion.ts, 8, 52))
var o5 = { ...union, ...union };
>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3))
>union : Symbol(union, Decl(spreadUnion.ts, 0, 3))
>union : Symbol(union, Decl(spreadUnion.ts, 0, 3))
@@ -0,0 +1,42 @@
=== tests/cases/compiler/spreadUnion.ts ===
var union: { a: number } | { b: string };
>union : { a: number; } | { b: string; }
>a : number
>b : string
var o3: { a: number } | { b: string };
>o3 : { a: number; } | { b: string; }
>a : number
>b : string
var o3 = { ...union };
>o3 : { a: number; } | { b: string; }
>{ ...union } : { a: number; } | { b: string; }
>union : { a: number; } | { b: string; }
var o4: { a: boolean } | { b: string , a: boolean};
>o4 : { a: boolean; } | { b: string; a: boolean; }
>a : boolean
>b : string
>a : boolean
var o4 = { ...union, a: false };
>o4 : { a: boolean; } | { b: string; a: boolean; }
>{ ...union, a: false } : { a: boolean; } | { a: boolean; b: string; }
>union : { a: number; } | { b: string; }
>a : boolean
>false : false
var o5: { a: number } | { b: string } | { a: number, b: string };
>o5 : { a: number; } | { b: string; } | { a: number; b: string; }
>a : number
>b : string
>a : number
>b : string
var o5 = { ...union, ...union };
>o5 : { a: number; } | { b: string; } | { a: number; b: string; }
>{ ...union, ...union } : { a: number; } | { b: string; a: number; } | { a: number; b: string; } | { b: string; }
>union : { a: number; } | { b: string; }
>union : { a: number; } | { b: string; }
+49
View File
@@ -0,0 +1,49 @@
//// [spreadUnion2.ts]
declare const undefinedUnion: { a: number } | undefined;
declare const nullUnion: { b: number } | null;
declare const nullAndUndefinedUnion: null | undefined;
var o1: { a: number };
var o1 = { ...undefinedUnion };
var o2: { b: number };
var o2 = { ...nullUnion };
var o3: { a: number, b: number };
var o3 = { ...undefinedUnion, ...nullUnion };
var o3 = { ...nullUnion, ...undefinedUnion };
var o4: { a: number };
var o4 = { ...undefinedUnion, ...undefinedUnion };
var o5: { b: number };
var o5 = { ...nullUnion, ...nullUnion };
var o6: { };
var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion };
var o6 = { ...nullAndUndefinedUnion };
//// [spreadUnion2.js]
var __assign = (this && this.__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;
};
var o1;
var o1 = __assign({}, undefinedUnion);
var o2;
var o2 = __assign({}, nullUnion);
var o3;
var o3 = __assign({}, undefinedUnion, nullUnion);
var o3 = __assign({}, nullUnion, undefinedUnion);
var o4;
var o4 = __assign({}, undefinedUnion, undefinedUnion);
var o5;
var o5 = __assign({}, nullUnion, nullUnion);
var o6;
var o6 = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion);
var o6 = __assign({}, nullAndUndefinedUnion);
@@ -0,0 +1,74 @@
=== tests/cases/compiler/spreadUnion2.ts ===
declare const undefinedUnion: { a: number } | undefined;
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
>a : Symbol(a, Decl(spreadUnion2.ts, 1, 31))
declare const nullUnion: { b: number } | null;
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
>b : Symbol(b, Decl(spreadUnion2.ts, 2, 26))
declare const nullAndUndefinedUnion: null | undefined;
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13))
var o1: { a: number };
>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3))
>a : Symbol(a, Decl(spreadUnion2.ts, 5, 9))
var o1 = { ...undefinedUnion };
>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3))
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
var o2: { b: number };
>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3))
>b : Symbol(b, Decl(spreadUnion2.ts, 8, 9))
var o2 = { ...nullUnion };
>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3))
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
var o3: { a: number, b: number };
>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3))
>a : Symbol(a, Decl(spreadUnion2.ts, 11, 9))
>b : Symbol(b, Decl(spreadUnion2.ts, 11, 20))
var o3 = { ...undefinedUnion, ...nullUnion };
>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3))
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
var o3 = { ...nullUnion, ...undefinedUnion };
>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3))
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
var o4: { a: number };
>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3))
>a : Symbol(a, Decl(spreadUnion2.ts, 15, 9))
var o4 = { ...undefinedUnion, ...undefinedUnion };
>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3))
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13))
var o5: { b: number };
>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3))
>b : Symbol(b, Decl(spreadUnion2.ts, 18, 9))
var o5 = { ...nullUnion, ...nullUnion };
>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3))
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13))
var o6: { };
>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3))
var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion };
>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3))
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13))
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13))
var o6 = { ...nullAndUndefinedUnion };
>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3))
>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13))
@@ -0,0 +1,84 @@
=== tests/cases/compiler/spreadUnion2.ts ===
declare const undefinedUnion: { a: number } | undefined;
>undefinedUnion : { a: number; } | undefined
>a : number
declare const nullUnion: { b: number } | null;
>nullUnion : { b: number; } | null
>b : number
>null : null
declare const nullAndUndefinedUnion: null | undefined;
>nullAndUndefinedUnion : null | undefined
>null : null
var o1: { a: number };
>o1 : { a: number; }
>a : number
var o1 = { ...undefinedUnion };
>o1 : { a: number; }
>{ ...undefinedUnion } : { a: number; }
>undefinedUnion : { a: number; } | undefined
var o2: { b: number };
>o2 : { b: number; }
>b : number
var o2 = { ...nullUnion };
>o2 : { b: number; }
>{ ...nullUnion } : { b: number; }
>nullUnion : { b: number; } | null
var o3: { a: number, b: number };
>o3 : { a: number; b: number; }
>a : number
>b : number
var o3 = { ...undefinedUnion, ...nullUnion };
>o3 : { a: number; b: number; }
>{ ...undefinedUnion, ...nullUnion } : { b: number; a: number; }
>undefinedUnion : { a: number; } | undefined
>nullUnion : { b: number; } | null
var o3 = { ...nullUnion, ...undefinedUnion };
>o3 : { a: number; b: number; }
>{ ...nullUnion, ...undefinedUnion } : { a: number; b: number; }
>nullUnion : { b: number; } | null
>undefinedUnion : { a: number; } | undefined
var o4: { a: number };
>o4 : { a: number; }
>a : number
var o4 = { ...undefinedUnion, ...undefinedUnion };
>o4 : { a: number; }
>{ ...undefinedUnion, ...undefinedUnion } : { a: number; }
>undefinedUnion : { a: number; } | undefined
>undefinedUnion : { a: number; } | undefined
var o5: { b: number };
>o5 : { b: number; }
>b : number
var o5 = { ...nullUnion, ...nullUnion };
>o5 : { b: number; }
>{ ...nullUnion, ...nullUnion } : { b: number; }
>nullUnion : { b: number; } | null
>nullUnion : { b: number; } | null
var o6: { };
>o6 : {}
var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion };
>o6 : {}
>{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {}
>nullAndUndefinedUnion : null | undefined
>nullAndUndefinedUnion : null | undefined
var o6 = { ...nullAndUndefinedUnion };
>o6 : {}
>{ ...nullAndUndefinedUnion } : {}
>nullAndUndefinedUnion : null | undefined
@@ -0,0 +1,10 @@
//// [unionTypeWithLeadingOperator.ts]
type A = | string;
type B =
| { type: "INCREMENT" }
| { type: "DECREMENT" };
type C = [| 0 | 1, | "foo" | "bar"];
//// [unionTypeWithLeadingOperator.js]
@@ -0,0 +1,16 @@
=== tests/cases/compiler/unionTypeWithLeadingOperator.ts ===
type A = | string;
>A : Symbol(A, Decl(unionTypeWithLeadingOperator.ts, 0, 0))
type B =
>B : Symbol(B, Decl(unionTypeWithLeadingOperator.ts, 0, 18))
| { type: "INCREMENT" }
>type : Symbol(type, Decl(unionTypeWithLeadingOperator.ts, 2, 5))
| { type: "DECREMENT" };
>type : Symbol(type, Decl(unionTypeWithLeadingOperator.ts, 3, 5))
type C = [| 0 | 1, | "foo" | "bar"];
>C : Symbol(C, Decl(unionTypeWithLeadingOperator.ts, 3, 26))
@@ -0,0 +1,16 @@
=== tests/cases/compiler/unionTypeWithLeadingOperator.ts ===
type A = | string;
>A : string
type B =
>B : B
| { type: "INCREMENT" }
>type : "INCREMENT"
| { type: "DECREMENT" };
>type : "DECREMENT"
type C = [| 0 | 1, | "foo" | "bar"];
>C : [0 | 1, "foo" | "bar"]
@@ -22,38 +22,38 @@ for (var x of Object.values(o)) {
}
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
>entries : ["a" | "b", number][]
>Object.entries(o) : ["a" | "b", number][]
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : [string, number][]
>Object.entries(o) : [string, number][]
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>o : { a: number; b: number; }
var entries1 = Object.entries(1); // <-- entries: [string, any][]
>entries1 : [string, any][]
>Object.entries(1) : [string, any][]
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>1 : 1
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
>entries2 : ["a" | "b", number | boolean][]
>Object.entries({a: true, b: 2}) : ["a" | "b", number | boolean][]
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries2 : [string, number | boolean][]
>Object.entries({a: true, b: 2}) : [string, number | boolean][]
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>{a: true, b: 2} : { a: true; b: number; }
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>{a: true, b: 2} : { a: true; b: 2; }
>a : boolean
>true : true
>b : number
>2 : 2
var entries3 = Object.entries({}) // [never, any][]
>entries3 : [never, any][]
>Object.entries({}) : [never, any][]
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries3 : [string, {}][]
>Object.entries({}) : [string, {}][]
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>{} : {}
@@ -22,10 +22,10 @@ for (var x of Object.values(o)) {
}
var entries = Object.entries(o);
>entries : ["a" | "b", number][]
>Object.entries(o) : ["a" | "b", number][]
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : [string, number][]
>Object.entries(o) : [string, number][]
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
>o : { a: number; b: number; }
@@ -0,0 +1,5 @@
// @declaration: true
export interface Test {
[index: TypeNotFound]: any;
}
@@ -0,0 +1,18 @@
// @noemithelpers: true
// @experimentaldecorators: true
declare var console : { log(arg: string): void };
function dec(): Function {
return function (target: any, propKey: string, descr: PropertyDescriptor): void {
console.log(target[propKey]);
//logs undefined
//propKey has three underscores as prefix, but the method has only two underscores
};
}
class A {
@dec()
private __foo(bar: string): void {
// do something with bar
}
}
@@ -0,0 +1,18 @@
// @strictNullChecks: true
// Repro from #12529
class A {
readonly kind = "A"; // (property) A.kind: "A"
}
class B {
readonly kind = "B"; // (property) B.kind: "B"
}
function f(value: A | B): number {
switch(value.kind) {
case "A": return 0;
case "B": return 1;
}
}
@@ -57,4 +57,49 @@ function getValueAsString(value: IntersectionFail): string {
return '' + value.num;
}
return value.str;
}
// Repro from #12535
namespace enums {
export const enum A {
a1,
a2,
a3,
// ... elements omitted for the sake of clarity
a75,
a76,
a77,
}
export const enum B {
b1,
b2,
// ... elements omitted for the sake of clarity
b86,
b87,
}
export const enum C {
c1,
c2,
// ... elements omitted for the sake of clarity
c210,
c211,
}
export type Genre = A | B | C;
}
type Foo = {
genreId: enums.Genre;
};
type Bar = {
genreId: enums.Genre;
};
type FooBar = Foo & Bar;
function foo(so: any) {
const val = so as FooBar;
const isGenre = val.genreId;
return isGenre;
}
@@ -0,0 +1,6 @@
type A = & string;
type B =
& { foo: string }
& { bar: number };
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
+4
View File
@@ -0,0 +1,4 @@
var intersection: { x: number, y: number } & { w: string, z: string };
var rest1: { y: number, w: string, z: string };
var {x, ...rest1 } = intersection;
@@ -0,0 +1,59 @@
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var {...r1} = p1; // Error, generic type paramterre
var {...r2} = p2; // OK
var {...r3} = t; // Error, generic type paramter
var {...r4} = i; // Error, index access
var {...r5} = k; // Error, index
var {...r6} = mapped_generic; // Error, generic mapped object type
var {...r7} = mapped; // OK, non-generic mapped type
var {...r8} = union_generic; // Error, union with generic type parameter
var {...r9} = union_primitive; // Error, union with generic type parameter
var {...r10} = intersection_generic; // Error, intersection with generic type parameter
var {...r11} = intersection_premitive; // Error, intersection with generic type parameter
var {...r12} = num; // Error
var {...r13} = str; // Error
var {...r14} = u; // OK
var {...r15} = n; // OK
var {...r16} = a; // OK
var {...r17} = literal_string; // Error
var {...r18} = literal_number; // Error
var {...r19} = e; // Error, enum
}
+14
View File
@@ -0,0 +1,14 @@
var union: { a: number, c: boolean } | { a: string, b: string };
var rest1: { c: boolean } | { b: string };
var {a, ...rest1 } = union;
var undefinedUnion: { n: number } | undefined;
var rest2: {};
var {n, ...rest2 } = undefinedUnion;
var nullUnion: { n: number } | null;
var rest3: {};
var {n, ...rest3 } = nullUnion;
+19
View File
@@ -0,0 +1,19 @@
// @strictNullChecks: true
declare const undefinedUnion: { n: number } | undefined;
var rest2: { n: number };
var {...rest2 } = undefinedUnion;
declare const nullUnion: { n: number } | null;
var rest3: { n: number };
var {...rest3 } = nullUnion;
declare const nullAndUndefinedUnion: null | undefined;
var rest4: { };
var {...rest4 } = nullAndUndefinedUnion;
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null;
var rest5: { n: number, s: string };
var {...rest5 } = unionWithIntersection;
@@ -0,0 +1,7 @@
var intersection: { a: number } & { b: string };
var o1: { a: number, b: string };
var o1 = { ...intersection };
var o2: { a: number, b: string, c: boolean };
var o2 = { ...intersection, c: false };
@@ -0,0 +1,59 @@
enum E { v1, v2 };
function f<T extends { b: string }>(p1: T, p2: T[]) {
var t: T;
var i: T["b"];
var k: keyof T;
var mapped_generic: {[P in keyof T]: T[P]};
var mapped: {[P in "b"]: T[P]};
var union_generic: T | { a: number };
var union_primitive: { a: number } | number;
var intersection_generic: T & { a: number };
var intersection_premitive: { a: number } | string;
var num: number;
var str: number;
var u: undefined;
var n: null;
var a: any;
var literal_string: "string";
var literal_number: 42;
var e: E;
var o1 = { ...p1 }; // Error, generic type paramterre
var o2 = { ...p2 }; // OK
var o3 = { ...t }; // Error, generic type paramter
var o4 = { ...i }; // Error, index access
var o5 = { ...k }; // Error, index
var o6 = { ...mapped_generic }; // Error, generic mapped object type
var o7 = { ...mapped }; // OK, non-generic mapped type
var o8 = { ...union_generic }; // Error, union with generic type parameter
var o9 = { ...union_primitive }; // Error, union with generic type parameter
var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter
var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter
var o12 = { ...num }; // Error
var o13 = { ...str }; // Error
var o14 = { ...u }; // OK
var o15 = { ...n }; // OK
var o16 = { ...a }; // OK
var o17 = { ...literal_string }; // Error
var o18 = { ...literal_number }; // Error
var o19 = { ...e }; // Error, enum
}
+10
View File
@@ -0,0 +1,10 @@
var union: { a: number } | { b: string };
var o3: { a: number } | { b: string };
var o3 = { ...union };
var o4: { a: boolean } | { b: string , a: boolean};
var o4 = { ...union, a: false };
var o5: { a: number } | { b: string } | { a: number, b: string };
var o5 = { ...union, ...union };

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