mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-16 05:58:32 -06:00
Merge pull request #12546 from Microsoft/mergeMaster1128
Merge master1128
This commit is contained in:
commit
6e2db6c771
@ -3205,7 +3205,7 @@ namespace ts {
|
||||
// right hand expression is of a type parameter type.
|
||||
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
|
||||
const indexType = getIndexType(checkNonNullExpression((<ForInStatement>declaration.parent.parent).expression));
|
||||
return indexType.flags & TypeFlags.Index ? indexType : stringType;
|
||||
return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? indexType : stringType;
|
||||
}
|
||||
|
||||
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
@ -4494,7 +4494,6 @@ 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,
|
||||
@ -4529,16 +4528,8 @@ namespace ts {
|
||||
else if (t.flags & TypeFlags.String) {
|
||||
stringIndexInfo = createIndexInfo(propType, isReadonly);
|
||||
}
|
||||
else if (t.flags & TypeFlags.Number) {
|
||||
numberIndexInfo = createIndexInfo(propType, isReadonly);
|
||||
}
|
||||
});
|
||||
// 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) {
|
||||
@ -5637,6 +5628,7 @@ namespace ts {
|
||||
containsString?: boolean;
|
||||
containsNumber?: boolean;
|
||||
containsStringOrNumberLiteral?: boolean;
|
||||
unionIndex?: number;
|
||||
}
|
||||
|
||||
function binarySearchTypes(types: Type[], type: Type): number {
|
||||
@ -5831,6 +5823,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);
|
||||
}
|
||||
}
|
||||
@ -5857,15 +5852,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) {
|
||||
@ -5874,6 +5860,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) {
|
||||
@ -5920,6 +5914,11 @@ namespace ts {
|
||||
getLiteralTypeFromPropertyNames(type);
|
||||
}
|
||||
|
||||
function getIndexTypeOrString(type: Type): Type {
|
||||
const indexType = getIndexType(type);
|
||||
return indexType !== neverType ? indexType : stringType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
@ -6018,8 +6017,7 @@ namespace ts {
|
||||
// meaningfully access the properties of the object type. In those cases, we first check that the
|
||||
// index type is assignable to 'keyof T' for the object type.
|
||||
if (accessNode) {
|
||||
const keyType = indexType.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType : indexType;
|
||||
if (!isTypeAssignableTo(keyType, getIndexType(objectType))) {
|
||||
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
|
||||
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
|
||||
return unknownType;
|
||||
}
|
||||
@ -8425,7 +8423,7 @@ namespace ts {
|
||||
// results for union and intersection types for performance reasons.
|
||||
function couldContainTypeParameters(type: Type): boolean {
|
||||
const objectFlags = getObjectFlags(type);
|
||||
return !!(type.flags & TypeFlags.TypeParameter ||
|
||||
return !!(type.flags & (TypeFlags.TypeParameter | TypeFlags.IndexedAccess) ||
|
||||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
|
||||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
|
||||
objectFlags & ObjectFlags.Mapped ||
|
||||
@ -8443,8 +8441,57 @@ namespace ts {
|
||||
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
|
||||
}
|
||||
|
||||
function inferTypes(context: InferenceContext, originalSource: Type, originalTarget: Type) {
|
||||
const typeParameters = context.signature.typeParameters;
|
||||
// Infer a suitable input type for an isomorphic mapped type { [P in keyof T]: X }. We construct
|
||||
// an object type with the same set of properties as the source type, where the type of each
|
||||
// property is computed by inferring from the source property type to X for a synthetic type
|
||||
// parameter T[P] (i.e. we treat the type T[P] as the type parameter we're inferring for).
|
||||
function inferTypeForIsomorphicMappedType(source: Type, target: MappedType): Type {
|
||||
if (!isMappableType(source)) {
|
||||
return source;
|
||||
}
|
||||
const typeParameter = getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
|
||||
const typeParameterArray = [typeParameter];
|
||||
const typeInferences = createTypeInferencesObject();
|
||||
const typeInferencesArray = [typeInferences];
|
||||
const templateType = getTemplateTypeFromMappedType(target);
|
||||
const properties = getPropertiesOfType(source);
|
||||
const members = createSymbolTable(properties);
|
||||
let hasInferredTypes = false;
|
||||
for (const prop of properties) {
|
||||
const inferredPropType = inferTargetType(getTypeOfSymbol(prop));
|
||||
if (inferredPropType) {
|
||||
const inferredProp = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | prop.flags & SymbolFlags.Optional, prop.name);
|
||||
inferredProp.declarations = prop.declarations;
|
||||
inferredProp.type = inferredPropType;
|
||||
inferredProp.isReadonly = isReadonlySymbol(prop);
|
||||
members[prop.name] = inferredProp;
|
||||
hasInferredTypes = true;
|
||||
}
|
||||
}
|
||||
let indexInfo = getIndexInfoOfType(source, IndexKind.String);
|
||||
if (indexInfo) {
|
||||
const inferredIndexType = inferTargetType(indexInfo.type);
|
||||
if (inferredIndexType) {
|
||||
indexInfo = createIndexInfo(inferredIndexType, indexInfo.isReadonly);
|
||||
hasInferredTypes = true;
|
||||
}
|
||||
}
|
||||
return hasInferredTypes ? createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined) : source;
|
||||
|
||||
function inferTargetType(sourceType: Type): Type {
|
||||
typeInferences.primary = undefined;
|
||||
typeInferences.secondary = undefined;
|
||||
inferTypes(typeParameterArray, typeInferencesArray, sourceType, templateType);
|
||||
const inferences = typeInferences.primary || typeInferences.secondary;
|
||||
return inferences && getUnionType(inferences, /*subtypeReduction*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
function inferTypesWithContext(context: InferenceContext, originalSource: Type, originalTarget: Type) {
|
||||
inferTypes(context.signature.typeParameters, context.inferences, originalSource, originalTarget);
|
||||
}
|
||||
|
||||
function inferTypes(typeParameters: Type[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
|
||||
let sourceStack: Type[];
|
||||
let targetStack: Type[];
|
||||
let depth = 0;
|
||||
@ -8512,7 +8559,7 @@ namespace ts {
|
||||
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, matchingTypes);
|
||||
}
|
||||
}
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
if (target.flags & (TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
|
||||
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
|
||||
@ -8524,7 +8571,7 @@ namespace ts {
|
||||
}
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
if (target === typeParameters[i]) {
|
||||
const inferences = context.inferences[i];
|
||||
const inferences = typeInferences[i];
|
||||
if (!inferences.isFixed) {
|
||||
// Any inferences that are made to a type parameter in a union type are inferior
|
||||
// to inferences made to a flat (non-union) type. This is because if we infer to
|
||||
@ -8538,7 +8585,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;
|
||||
}
|
||||
}
|
||||
@ -8586,19 +8633,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
|
||||
if (getObjectFlags(source) & ObjectFlags.Mapped) {
|
||||
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
|
||||
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
return;
|
||||
}
|
||||
if (constraintType.flags & TypeFlags.TypeParameter) {
|
||||
inferFromTypes(getIndexType(source), constraintType);
|
||||
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
return;
|
||||
}
|
||||
}
|
||||
source = getApparentType(source);
|
||||
if (source.flags & TypeFlags.Object) {
|
||||
if (isInProcess(source, target)) {
|
||||
@ -8619,15 +8653,39 @@ namespace ts {
|
||||
sourceStack[depth] = source;
|
||||
targetStack[depth] = target;
|
||||
depth++;
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
inferFromObjectTypes(source, target);
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromObjectTypes(source: Type, target: Type) {
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
|
||||
if (constraintType.flags & TypeFlags.Index) {
|
||||
// We're inferring from some source type S to an isomorphic mapped type { [P in keyof T]: X },
|
||||
// where T is a type parameter. Use inferTypeForIsomorphicMappedType to infer a suitable source
|
||||
// type and then infer from that type to T.
|
||||
const index = indexOf(typeParameters, (<IndexType>constraintType).type);
|
||||
if (index >= 0 && !typeInferences[index].isFixed) {
|
||||
inferFromTypes(inferTypeForIsomorphicMappedType(source, <MappedType>target), typeParameters[index]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (constraintType.flags & TypeFlags.TypeParameter) {
|
||||
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
|
||||
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
|
||||
inferFromTypes(getIndexType(source), constraintType);
|
||||
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
return;
|
||||
}
|
||||
}
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
}
|
||||
|
||||
function inferFromProperties(source: Type, target: Type) {
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
@ -12458,7 +12516,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));
|
||||
}
|
||||
@ -12493,7 +12551,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
|
||||
@ -12515,7 +12573,7 @@ namespace ts {
|
||||
argType = checkExpressionWithContextualType(arg, paramType, mapper);
|
||||
}
|
||||
|
||||
inferTypes(context, argType, paramType);
|
||||
inferTypesWithContext(context, argType, paramType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12530,7 +12588,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13617,7 +13675,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13703,7 +13761,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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -13839,7 +13897,7 @@ namespace ts {
|
||||
if (!switchTypes.length) {
|
||||
return false;
|
||||
}
|
||||
return eachTypeContainedIn(type, switchTypes);
|
||||
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
|
||||
}
|
||||
|
||||
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
|
||||
@ -14275,7 +14333,7 @@ namespace ts {
|
||||
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
|
||||
// and the right operand to be of type Any, an object type, or a type parameter type.
|
||||
// The result is always of the Boolean primitive type.
|
||||
if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
|
||||
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
|
||||
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
|
||||
}
|
||||
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
|
||||
@ -17166,6 +17224,7 @@ namespace ts {
|
||||
// Grammar checking
|
||||
checkGrammarForInOrForOfStatement(node);
|
||||
|
||||
const rightType = checkNonNullExpression(node.expression);
|
||||
// TypeScript 1.0 spec (April 2014): 5.4
|
||||
// In a 'for-in' statement of the form
|
||||
// for (let VarDecl in Expr) Statement
|
||||
@ -17176,7 +17235,6 @@ namespace ts {
|
||||
if (variable && isBindingPattern(variable.name)) {
|
||||
error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
|
||||
}
|
||||
|
||||
checkForInOrForOfVariableDeclaration(node);
|
||||
}
|
||||
else {
|
||||
@ -17189,7 +17247,7 @@ namespace ts {
|
||||
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
|
||||
}
|
||||
else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike)) {
|
||||
else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
|
||||
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
|
||||
}
|
||||
else {
|
||||
@ -17198,7 +17256,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const rightType = checkNonNullExpression(node.expression);
|
||||
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
|
||||
// in this case error about missing name is already reported - do not report extra one
|
||||
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -1353,13 +1353,13 @@ namespace ts {
|
||||
// __metadata("design:type", Function),
|
||||
// __metadata("design:paramtypes", [Object]),
|
||||
// __metadata("design:returntype", void 0)
|
||||
// ], C.prototype, "method", undefined);
|
||||
// ], C.prototype, "method", null);
|
||||
//
|
||||
// The emit for an accessor is:
|
||||
//
|
||||
// __decorate([
|
||||
// dec
|
||||
// ], C.prototype, "accessor", undefined);
|
||||
// ], C.prototype, "accessor", null);
|
||||
//
|
||||
// The emit for a property is:
|
||||
//
|
||||
|
||||
@ -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,8 +1,6 @@
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
|
||||
@ -19,7 +17,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
|
||||
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ====
|
||||
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (17 errors) ====
|
||||
enum E { a }
|
||||
|
||||
var x: any;
|
||||
@ -42,11 +40,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
|
||||
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
var ra4 = a4 in x;
|
||||
var ra5 = null in x;
|
||||
~~~~
|
||||
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
var ra6 = undefined in x;
|
||||
~~~~~~~~~
|
||||
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
var ra7 = E.a in x;
|
||||
var ra8 = false in x;
|
||||
~~~~~
|
||||
|
||||
@ -58,6 +58,51 @@ function getValueAsString(value: IntersectionFail): string {
|
||||
return '' + value.num;
|
||||
}
|
||||
return value.str;
|
||||
}
|
||||
|
||||
// Repro from #12535
|
||||
|
||||
namespace enums {
|
||||
export const enum A {
|
||||
a1,
|
||||
a2,
|
||||
a3,
|
||||
// ... elements omitted for the sake of clarity
|
||||
a75,
|
||||
a76,
|
||||
a77,
|
||||
}
|
||||
export const enum B {
|
||||
b1,
|
||||
b2,
|
||||
// ... elements omitted for the sake of clarity
|
||||
b86,
|
||||
b87,
|
||||
}
|
||||
export const enum C {
|
||||
c1,
|
||||
c2,
|
||||
// ... elements omitted for the sake of clarity
|
||||
c210,
|
||||
c211,
|
||||
}
|
||||
export type Genre = A | B | C;
|
||||
}
|
||||
|
||||
type Foo = {
|
||||
genreId: enums.Genre;
|
||||
};
|
||||
|
||||
type Bar = {
|
||||
genreId: enums.Genre;
|
||||
};
|
||||
|
||||
type FooBar = Foo & Bar;
|
||||
|
||||
function foo(so: any) {
|
||||
const val = so as FooBar;
|
||||
const isGenre = val.genreId;
|
||||
return isGenre;
|
||||
}
|
||||
|
||||
//// [intersectionTypeNormalization.js]
|
||||
@ -77,3 +122,8 @@ function getValueAsString(value) {
|
||||
}
|
||||
return value.str;
|
||||
}
|
||||
function foo(so) {
|
||||
var val = so;
|
||||
var isGenre = val.genreId;
|
||||
return isGenre;
|
||||
}
|
||||
|
||||
@ -240,3 +240,113 @@ function getValueAsString(value: IntersectionFail): string {
|
||||
>value : Symbol(value, Decl(intersectionTypeNormalization.ts, 54, 26))
|
||||
>str : Symbol(str, Decl(intersectionTypeNormalization.ts, 47, 35))
|
||||
}
|
||||
|
||||
// Repro from #12535
|
||||
|
||||
namespace enums {
|
||||
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
|
||||
|
||||
export const enum A {
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
|
||||
|
||||
a1,
|
||||
>a1 : Symbol(A.a1, Decl(intersectionTypeNormalization.ts, 64, 25))
|
||||
|
||||
a2,
|
||||
>a2 : Symbol(A.a2, Decl(intersectionTypeNormalization.ts, 65, 11))
|
||||
|
||||
a3,
|
||||
>a3 : Symbol(A.a3, Decl(intersectionTypeNormalization.ts, 66, 11))
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
a75,
|
||||
>a75 : Symbol(A.a75, Decl(intersectionTypeNormalization.ts, 67, 11))
|
||||
|
||||
a76,
|
||||
>a76 : Symbol(A.a76, Decl(intersectionTypeNormalization.ts, 69, 12))
|
||||
|
||||
a77,
|
||||
>a77 : Symbol(A.a77, Decl(intersectionTypeNormalization.ts, 70, 12))
|
||||
}
|
||||
export const enum B {
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
|
||||
|
||||
b1,
|
||||
>b1 : Symbol(B.b1, Decl(intersectionTypeNormalization.ts, 73, 25))
|
||||
|
||||
b2,
|
||||
>b2 : Symbol(B.b2, Decl(intersectionTypeNormalization.ts, 74, 11))
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
b86,
|
||||
>b86 : Symbol(B.b86, Decl(intersectionTypeNormalization.ts, 75, 11))
|
||||
|
||||
b87,
|
||||
>b87 : Symbol(B.b87, Decl(intersectionTypeNormalization.ts, 77, 12))
|
||||
}
|
||||
export const enum C {
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
|
||||
|
||||
c1,
|
||||
>c1 : Symbol(C.c1, Decl(intersectionTypeNormalization.ts, 80, 25))
|
||||
|
||||
c2,
|
||||
>c2 : Symbol(C.c2, Decl(intersectionTypeNormalization.ts, 81, 11))
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
c210,
|
||||
>c210 : Symbol(C.c210, Decl(intersectionTypeNormalization.ts, 82, 11))
|
||||
|
||||
c211,
|
||||
>c211 : Symbol(C.c211, Decl(intersectionTypeNormalization.ts, 84, 13))
|
||||
}
|
||||
export type Genre = A | B | C;
|
||||
>Genre : Symbol(Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
|
||||
>A : Symbol(A, Decl(intersectionTypeNormalization.ts, 63, 17))
|
||||
>B : Symbol(B, Decl(intersectionTypeNormalization.ts, 72, 5))
|
||||
>C : Symbol(C, Decl(intersectionTypeNormalization.ts, 79, 5))
|
||||
}
|
||||
|
||||
type Foo = {
|
||||
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
|
||||
|
||||
genreId: enums.Genre;
|
||||
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12))
|
||||
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
|
||||
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
|
||||
|
||||
};
|
||||
|
||||
type Bar = {
|
||||
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
|
||||
|
||||
genreId: enums.Genre;
|
||||
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 94, 12))
|
||||
>enums : Symbol(enums, Decl(intersectionTypeNormalization.ts, 59, 1))
|
||||
>Genre : Symbol(enums.Genre, Decl(intersectionTypeNormalization.ts, 86, 5))
|
||||
|
||||
};
|
||||
|
||||
type FooBar = Foo & Bar;
|
||||
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
|
||||
>Foo : Symbol(Foo, Decl(intersectionTypeNormalization.ts, 88, 1))
|
||||
>Bar : Symbol(Bar, Decl(intersectionTypeNormalization.ts, 92, 2))
|
||||
|
||||
function foo(so: any) {
|
||||
>foo : Symbol(foo, Decl(intersectionTypeNormalization.ts, 98, 24))
|
||||
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
|
||||
|
||||
const val = so as FooBar;
|
||||
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
|
||||
>so : Symbol(so, Decl(intersectionTypeNormalization.ts, 100, 13))
|
||||
>FooBar : Symbol(FooBar, Decl(intersectionTypeNormalization.ts, 96, 2))
|
||||
|
||||
const isGenre = val.genreId;
|
||||
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
|
||||
>val.genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
|
||||
>val : Symbol(val, Decl(intersectionTypeNormalization.ts, 101, 9))
|
||||
>genreId : Symbol(genreId, Decl(intersectionTypeNormalization.ts, 90, 12), Decl(intersectionTypeNormalization.ts, 94, 12))
|
||||
|
||||
return isGenre;
|
||||
>isGenre : Symbol(isGenre, Decl(intersectionTypeNormalization.ts, 102, 9))
|
||||
}
|
||||
|
||||
@ -244,3 +244,114 @@ function getValueAsString(value: IntersectionFail): string {
|
||||
>value : { kind: "string"; str: string; } & ToString
|
||||
>str : string
|
||||
}
|
||||
|
||||
// Repro from #12535
|
||||
|
||||
namespace enums {
|
||||
>enums : typeof enums
|
||||
|
||||
export const enum A {
|
||||
>A : A
|
||||
|
||||
a1,
|
||||
>a1 : A.a1
|
||||
|
||||
a2,
|
||||
>a2 : A.a2
|
||||
|
||||
a3,
|
||||
>a3 : A.a3
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
a75,
|
||||
>a75 : A.a75
|
||||
|
||||
a76,
|
||||
>a76 : A.a76
|
||||
|
||||
a77,
|
||||
>a77 : A.a77
|
||||
}
|
||||
export const enum B {
|
||||
>B : B
|
||||
|
||||
b1,
|
||||
>b1 : B.b1
|
||||
|
||||
b2,
|
||||
>b2 : B.b2
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
b86,
|
||||
>b86 : B.b86
|
||||
|
||||
b87,
|
||||
>b87 : B.b87
|
||||
}
|
||||
export const enum C {
|
||||
>C : C
|
||||
|
||||
c1,
|
||||
>c1 : C.c1
|
||||
|
||||
c2,
|
||||
>c2 : C.c2
|
||||
|
||||
// ... elements omitted for the sake of clarity
|
||||
c210,
|
||||
>c210 : C.c210
|
||||
|
||||
c211,
|
||||
>c211 : C.c211
|
||||
}
|
||||
export type Genre = A | B | C;
|
||||
>Genre : Genre
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
}
|
||||
|
||||
type Foo = {
|
||||
>Foo : Foo
|
||||
|
||||
genreId: enums.Genre;
|
||||
>genreId : enums.Genre
|
||||
>enums : any
|
||||
>Genre : enums.Genre
|
||||
|
||||
};
|
||||
|
||||
type Bar = {
|
||||
>Bar : Bar
|
||||
|
||||
genreId: enums.Genre;
|
||||
>genreId : enums.Genre
|
||||
>enums : any
|
||||
>Genre : enums.Genre
|
||||
|
||||
};
|
||||
|
||||
type FooBar = Foo & Bar;
|
||||
>FooBar : FooBar
|
||||
>Foo : Foo
|
||||
>Bar : Bar
|
||||
|
||||
function foo(so: any) {
|
||||
>foo : (so: any) => enums.Genre
|
||||
>so : any
|
||||
|
||||
const val = so as FooBar;
|
||||
>val : FooBar
|
||||
>so as FooBar : FooBar
|
||||
>so : any
|
||||
>FooBar : FooBar
|
||||
|
||||
const isGenre = val.genreId;
|
||||
>isGenre : enums.Genre
|
||||
>val.genreId : enums.Genre
|
||||
>val : FooBar
|
||||
>genreId : enums.Genre
|
||||
|
||||
return isGenre;
|
||||
>isGenre : enums.Genre
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
//// [intersectionTypeWithLeadingOperator.ts]
|
||||
type A = & string;
|
||||
type B =
|
||||
& { foo: string }
|
||||
& { bar: number };
|
||||
|
||||
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
|
||||
|
||||
|
||||
//// [intersectionTypeWithLeadingOperator.js]
|
||||
@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
|
||||
type A = & string;
|
||||
>A : Symbol(A, Decl(intersectionTypeWithLeadingOperator.ts, 0, 0))
|
||||
|
||||
type B =
|
||||
>B : Symbol(B, Decl(intersectionTypeWithLeadingOperator.ts, 0, 18))
|
||||
|
||||
& { foo: string }
|
||||
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 2, 5))
|
||||
|
||||
& { bar: number };
|
||||
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 3, 5))
|
||||
|
||||
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
|
||||
>C : Symbol(C, Decl(intersectionTypeWithLeadingOperator.ts, 3, 20))
|
||||
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 13))
|
||||
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 26))
|
||||
>foo : Symbol(foo, Decl(intersectionTypeWithLeadingOperator.ts, 5, 40))
|
||||
>bar : Symbol(bar, Decl(intersectionTypeWithLeadingOperator.ts, 5, 53))
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/intersectionTypeWithLeadingOperator.ts ===
|
||||
type A = & string;
|
||||
>A : string
|
||||
|
||||
type B =
|
||||
>B : B
|
||||
|
||||
& { foo: string }
|
||||
>foo : string
|
||||
|
||||
& { bar: number };
|
||||
>bar : number
|
||||
|
||||
type C = [& { foo: 1 } & { bar: 2 }, & { foo: 3 } & { bar: 4 }];
|
||||
>C : [{ foo: 1; } & { bar: 2; }, { foo: 3; } & { bar: 4; }]
|
||||
>foo : 1
|
||||
>bar : 2
|
||||
>foo : 3
|
||||
>bar : 4
|
||||
|
||||
222
tests/baselines/reference/isomorphicMappedTypeInference.js
Normal file
222
tests/baselines/reference/isomorphicMappedTypeInference.js
Normal file
@ -0,0 +1,222 @@
|
||||
//// [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];
|
||||
}
|
||||
|
||||
//// [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];
|
||||
}
|
||||
|
||||
|
||||
//// [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;
|
||||
334
tests/baselines/reference/isomorphicMappedTypeInference.symbols
Normal file
334
tests/baselines/reference/isomorphicMappedTypeInference.symbols
Normal file
@ -0,0 +1,334 @@
|
||||
=== 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))
|
||||
}
|
||||
405
tests/baselines/reference/isomorphicMappedTypeInference.types
Normal file
405
tests/baselines/reference/isomorphicMappedTypeInference.types
Normal file
@ -0,0 +1,405 @@
|
||||
=== 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
|
||||
}
|
||||
81
tests/baselines/reference/keyofAndForIn.js
Normal file
81
tests/baselines/reference/keyofAndForIn.js
Normal file
@ -0,0 +1,81 @@
|
||||
//// [keyofAndForIn.ts]
|
||||
|
||||
// Repro from #12513
|
||||
|
||||
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
const b = k in obj;
|
||||
let k1: K;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
const b = k in obj;
|
||||
let k1: keyof T;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
const b = k in obj;
|
||||
let k1: K;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
//// [keyofAndForIn.js]
|
||||
// Repro from #12513
|
||||
function f1(obj, k) {
|
||||
var b = k in obj;
|
||||
var k1;
|
||||
for (k1 in obj) {
|
||||
var x1 = obj[k1];
|
||||
}
|
||||
for (var k2 in obj) {
|
||||
var x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
function f2(obj, k) {
|
||||
var b = k in obj;
|
||||
var k1;
|
||||
for (k1 in obj) {
|
||||
var x1 = obj[k1];
|
||||
}
|
||||
for (var k2 in obj) {
|
||||
var x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
function f3(obj, k) {
|
||||
var b = k in obj;
|
||||
var k1;
|
||||
for (k1 in obj) {
|
||||
var x1 = obj[k1];
|
||||
}
|
||||
for (var k2 in obj) {
|
||||
var x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [keyofAndForIn.d.ts]
|
||||
declare function f1<K extends string, T>(obj: {
|
||||
[P in K]: T;
|
||||
}, k: K): void;
|
||||
declare function f2<T>(obj: {
|
||||
[P in keyof T]: T[P];
|
||||
}, k: keyof T): void;
|
||||
declare function f3<T, K extends keyof T>(obj: {
|
||||
[P in K]: T[P];
|
||||
}, k: K): void;
|
||||
125
tests/baselines/reference/keyofAndForIn.symbols
Normal file
125
tests/baselines/reference/keyofAndForIn.symbols
Normal file
@ -0,0 +1,125 @@
|
||||
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
|
||||
|
||||
// Repro from #12513
|
||||
|
||||
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
>f1 : Symbol(f1, Decl(keyofAndForIn.ts, 0, 0))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
>P : Symbol(P, Decl(keyofAndForIn.ts, 3, 41))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
|
||||
|
||||
const b = k in obj;
|
||||
>b : Symbol(b, Decl(keyofAndForIn.ts, 4, 9))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
|
||||
let k1: K;
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 7, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 10, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
>f2 : Symbol(f2, Decl(keyofAndForIn.ts, 12, 1))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
|
||||
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
|
||||
|
||||
const b = k in obj;
|
||||
>b : Symbol(b, Decl(keyofAndForIn.ts, 15, 9))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
|
||||
let k1: keyof T;
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 18, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 21, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
>f3 : Symbol(f3, Decl(keyofAndForIn.ts, 23, 1))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
|
||||
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
|
||||
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
|
||||
|
||||
const b = k in obj;
|
||||
>b : Symbol(b, Decl(keyofAndForIn.ts, 26, 9))
|
||||
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
|
||||
let k1: K;
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
|
||||
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 29, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 32, 11))
|
||||
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
|
||||
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
|
||||
}
|
||||
}
|
||||
134
tests/baselines/reference/keyofAndForIn.types
Normal file
134
tests/baselines/reference/keyofAndForIn.types
Normal file
@ -0,0 +1,134 @@
|
||||
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
|
||||
|
||||
// Repro from #12513
|
||||
|
||||
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
>f1 : <K extends string, T>(obj: { [P in K]: T; }, k: K) => void
|
||||
>K : K
|
||||
>T : T
|
||||
>obj : { [P in K]: T; }
|
||||
>P : P
|
||||
>K : K
|
||||
>T : T
|
||||
>k : K
|
||||
>K : K
|
||||
|
||||
const b = k in obj;
|
||||
>b : boolean
|
||||
>k in obj : boolean
|
||||
>k : K
|
||||
>obj : { [P in K]: T; }
|
||||
|
||||
let k1: K;
|
||||
>k1 : K
|
||||
>K : K
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : K
|
||||
>obj : { [P in K]: T; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T
|
||||
>obj[k1] : T
|
||||
>obj : { [P in K]: T; }
|
||||
>k1 : K
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : K
|
||||
>obj : { [P in K]: T; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T
|
||||
>obj[k2] : T
|
||||
>obj : { [P in K]: T; }
|
||||
>k2 : K
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
>f2 : <T>(obj: { [P in keyof T]: T[P]; }, k: keyof T) => void
|
||||
>T : T
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
>P : P
|
||||
>T : T
|
||||
>T : T
|
||||
>P : P
|
||||
>k : keyof T
|
||||
>T : T
|
||||
|
||||
const b = k in obj;
|
||||
>b : boolean
|
||||
>k in obj : boolean
|
||||
>k : keyof T
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
|
||||
let k1: keyof T;
|
||||
>k1 : keyof T
|
||||
>T : T
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : keyof T
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T[keyof T]
|
||||
>obj[k1] : T[keyof T]
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
>k1 : keyof T
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : keyof T
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T[keyof T]
|
||||
>obj[k2] : T[keyof T]
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
>k2 : keyof T
|
||||
}
|
||||
}
|
||||
|
||||
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
>f3 : <T, K extends keyof T>(obj: { [P in K]: T[P]; }, k: K) => void
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>obj : { [P in K]: T[P]; }
|
||||
>P : P
|
||||
>K : K
|
||||
>T : T
|
||||
>P : P
|
||||
>k : K
|
||||
>K : K
|
||||
|
||||
const b = k in obj;
|
||||
>b : boolean
|
||||
>k in obj : boolean
|
||||
>k : K
|
||||
>obj : { [P in K]: T[P]; }
|
||||
|
||||
let k1: K;
|
||||
>k1 : K
|
||||
>K : K
|
||||
|
||||
for (k1 in obj) {
|
||||
>k1 : K
|
||||
>obj : { [P in K]: T[P]; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T[K]
|
||||
>obj[k1] : T[K]
|
||||
>obj : { [P in K]: T[P]; }
|
||||
>k1 : K
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
>k2 : K
|
||||
>obj : { [P in K]: T[P]; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T[K]
|
||||
>obj[k2] : T[K]
|
||||
>obj : { [P in K]: T[P]; }
|
||||
>k2 : K
|
||||
}
|
||||
}
|
||||
@ -21,11 +21,12 @@ class Options {
|
||||
}
|
||||
|
||||
type Dictionary<T> = { [x: string]: T };
|
||||
type NumericallyIndexed<T> = { [x: number]: T };
|
||||
|
||||
const enum E { A, B, C }
|
||||
|
||||
type K00 = keyof any; // string | number
|
||||
type K01 = keyof string; // number | "toString" | "charAt" | ...
|
||||
type K00 = keyof any; // string
|
||||
type K01 = keyof string; // "toString" | "charAt" | ...
|
||||
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
|
||||
type K03 = keyof boolean; // "valueOf"
|
||||
type K04 = keyof void; // never
|
||||
@ -34,19 +35,20 @@ type K06 = keyof null; // never
|
||||
type K07 = keyof never; // never
|
||||
|
||||
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
|
||||
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
|
||||
type K12 = keyof Dictionary<Shape>; // string | number
|
||||
type K11 = keyof Shape[]; // "length" | "toString" | ...
|
||||
type K12 = keyof Dictionary<Shape>; // string
|
||||
type K13 = keyof {}; // never
|
||||
type K14 = keyof Object; // "constructor" | "toString" | ...
|
||||
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
|
||||
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
|
||||
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
|
||||
type K17 = keyof (Shape | Item); // "name"
|
||||
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
|
||||
type K19 = keyof NumericallyIndexed<Shape> // never
|
||||
|
||||
type KeyOf<T> = keyof T;
|
||||
|
||||
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
|
||||
type K21 = KeyOf<Dictionary<Shape>>; // string | number
|
||||
type K21 = KeyOf<Dictionary<Shape>>; // string
|
||||
|
||||
type NAME = "name";
|
||||
type WIDTH_OR_HEIGHT = "width" | "height";
|
||||
@ -247,7 +249,8 @@ class OtherPerson {
|
||||
getParts() {
|
||||
return getProperty(this, "parts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [keyofAndIndexedAccess.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
@ -449,6 +452,9 @@ declare class Options {
|
||||
declare type Dictionary<T> = {
|
||||
[x: string]: T;
|
||||
};
|
||||
declare type NumericallyIndexed<T> = {
|
||||
[x: number]: T;
|
||||
};
|
||||
declare const enum E {
|
||||
A = 0,
|
||||
B = 1,
|
||||
@ -471,6 +477,7 @@ declare type K15 = keyof E;
|
||||
declare type K16 = keyof [string, number];
|
||||
declare type K17 = keyof (Shape | Item);
|
||||
declare type K18 = keyof (Shape & Item);
|
||||
declare type K19 = keyof NumericallyIndexed<Shape>;
|
||||
declare type KeyOf<T> = keyof T;
|
||||
declare type K20 = KeyOf<Shape>;
|
||||
declare type K21 = KeyOf<Dictionary<Shape>>;
|
||||
|
||||
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>
|
||||
@ -970,3 +981,4 @@ class OtherPerson {
|
||||
>"parts" : "parts"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
12
tests/baselines/reference/mappedTypeInferenceCircularity.js
Normal file
12
tests/baselines/reference/mappedTypeInferenceCircularity.js
Normal file
@ -0,0 +1,12 @@
|
||||
//// [mappedTypeInferenceCircularity.ts]
|
||||
// Repro from #12511
|
||||
|
||||
type HTML = { [K in 'div']: Block<HTML> };
|
||||
type Block<P> = <T>(func: HTML) => {};
|
||||
|
||||
declare var h: HTML;
|
||||
h.div(h);
|
||||
|
||||
//// [mappedTypeInferenceCircularity.js]
|
||||
// Repro from #12511
|
||||
h.div(h);
|
||||
@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
|
||||
// Repro from #12511
|
||||
|
||||
type HTML = { [K in 'div']: Block<HTML> };
|
||||
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
|
||||
>K : Symbol(K, Decl(mappedTypeInferenceCircularity.ts, 2, 15))
|
||||
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
|
||||
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
|
||||
|
||||
type Block<P> = <T>(func: HTML) => {};
|
||||
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
|
||||
>P : Symbol(P, Decl(mappedTypeInferenceCircularity.ts, 3, 11))
|
||||
>T : Symbol(T, Decl(mappedTypeInferenceCircularity.ts, 3, 17))
|
||||
>func : Symbol(func, Decl(mappedTypeInferenceCircularity.ts, 3, 20))
|
||||
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
|
||||
|
||||
declare var h: HTML;
|
||||
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
|
||||
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
|
||||
|
||||
h.div(h);
|
||||
>h.div : Symbol(div)
|
||||
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
|
||||
>div : Symbol(div)
|
||||
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
|
||||
// Repro from #12511
|
||||
|
||||
type HTML = { [K in 'div']: Block<HTML> };
|
||||
>HTML : HTML
|
||||
>K : K
|
||||
>Block : Block<P>
|
||||
>HTML : HTML
|
||||
|
||||
type Block<P> = <T>(func: HTML) => {};
|
||||
>Block : Block<P>
|
||||
>P : P
|
||||
>T : T
|
||||
>func : HTML
|
||||
>HTML : HTML
|
||||
|
||||
declare var h: HTML;
|
||||
>h : HTML
|
||||
>HTML : HTML
|
||||
|
||||
h.div(h);
|
||||
>h.div(h) : {}
|
||||
>h.div : Block<HTML>
|
||||
>h : HTML
|
||||
>div : Block<HTML>
|
||||
>h : HTML
|
||||
|
||||
10
tests/baselines/reference/unionTypeWithLeadingOperator.js
Normal file
10
tests/baselines/reference/unionTypeWithLeadingOperator.js
Normal file
@ -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))
|
||||
|
||||
16
tests/baselines/reference/unionTypeWithLeadingOperator.types
Normal file
16
tests/baselines/reference/unionTypeWithLeadingOperator.types
Normal file
@ -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"]
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
tests/cases/compiler/widenedTypes.ts(2,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.
|
||||
tests/cases/compiler/widenedTypes.ts(5,1): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
tests/cases/compiler/widenedTypes.ts(6,7): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
|
||||
tests/cases/compiler/widenedTypes.ts(8,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
|
||||
tests/cases/compiler/widenedTypes.ts(10,14): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
@ -12,7 +11,7 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y:
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/widenedTypes.ts (9 errors) ====
|
||||
==== tests/cases/compiler/widenedTypes.ts (8 errors) ====
|
||||
|
||||
null instanceof (() => { });
|
||||
~~~~
|
||||
@ -20,8 +19,6 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y:
|
||||
({}) instanceof null; // Ok because null is a subtype of function
|
||||
|
||||
null in {};
|
||||
~~~~
|
||||
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
|
||||
"" in null;
|
||||
~~~~
|
||||
!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
|
||||
|
||||
@ -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 }];
|
||||
7
tests/cases/compiler/mappedTypeInferenceCircularity.ts
Normal file
7
tests/cases/compiler/mappedTypeInferenceCircularity.ts
Normal file
@ -0,0 +1,7 @@
|
||||
// Repro from #12511
|
||||
|
||||
type HTML = { [K in 'div']: Block<HTML> };
|
||||
type Block<P> = <T>(func: HTML) => {};
|
||||
|
||||
declare var h: HTML;
|
||||
h.div(h);
|
||||
6
tests/cases/compiler/unionTypeWithLeadingOperator.ts
Normal file
6
tests/cases/compiler/unionTypeWithLeadingOperator.ts
Normal file
@ -0,0 +1,6 @@
|
||||
type A = | string;
|
||||
type B =
|
||||
| { type: "INCREMENT" }
|
||||
| { type: "DECREMENT" };
|
||||
|
||||
type C = [| 0 | 1, | "foo" | "bar"];
|
||||
36
tests/cases/conformance/types/keyof/keyofAndForIn.ts
Normal file
36
tests/cases/conformance/types/keyof/keyofAndForIn.ts
Normal file
@ -0,0 +1,36 @@
|
||||
// @declaration: true
|
||||
|
||||
// Repro from #12513
|
||||
|
||||
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
const b = k in obj;
|
||||
let k1: K;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
const b = k in obj;
|
||||
let k1: keyof T;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
|
||||
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
const b = k in obj;
|
||||
let k1: K;
|
||||
for (k1 in obj) {
|
||||
let x1 = obj[k1];
|
||||
}
|
||||
for (let k2 in obj) {
|
||||
let x2 = obj[k2];
|
||||
}
|
||||
}
|
||||
@ -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";
|
||||
@ -247,4 +249,4 @@ class OtherPerson {
|
||||
getParts() {
|
||||
return getProperty(this, "parts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
// @noimplicitany: true
|
||||
// @declaration: true
|
||||
|
||||
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];
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user