diff --git a/.github/ISSUE_TEMPLATE/lib_change.yml b/.github/ISSUE_TEMPLATE/lib_change.yml index 8d965d56722..21312c88e12 100644 --- a/.github/ISSUE_TEMPLATE/lib_change.yml +++ b/.github/ISSUE_TEMPLATE/lib_change.yml @@ -1,5 +1,5 @@ name: 'Library change' -description: 'Fix or improve issues with built-in type definitions like `lib.dom.d.ts`, `lib.es6.d.ts`, etc.' +description: 'Fix or improve issues with built-in type definitions like `lib.es6.d.ts`, etc.' body: - type: markdown attributes: diff --git a/package-lock.json b/package-lock.json index 5a1d304bceb..c45b0309631 100644 --- a/package-lock.json +++ b/package-lock.json @@ -568,9 +568,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", - "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -591,9 +591,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", - "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -951,9 +951,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz", - "integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==", + "version": "20.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", + "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1839,15 +1839,15 @@ } }, "node_modules/eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", - "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.54.0", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4258,9 +4258,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", - "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -4275,9 +4275,9 @@ } }, "@eslint/js": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", - "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true }, "@humanwhocodes/config-array": { @@ -4565,9 +4565,9 @@ "dev": true }, "@types/node": { - "version": "20.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz", - "integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==", + "version": "20.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", + "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", "dev": true, "requires": { "undici-types": "~5.26.4" @@ -5206,15 +5206,15 @@ "dev": true }, "eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", - "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.54.0", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 93a0a819657..d96155173c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -597,6 +597,7 @@ import { isJSDocSatisfiesTag, isJSDocSignature, isJSDocTemplateTag, + isJSDocThisTag, isJSDocTypeAlias, isJSDocTypeAssertion, isJSDocTypedefTag, @@ -1304,6 +1305,12 @@ const enum MappedTypeModifiers { ExcludeOptional = 1 << 3, } +const enum MappedTypeNameTypeKind { + None, + Filtering, + Remapping, +} + const enum ExpandingFlags { None = 0, Source = 1, @@ -2831,7 +2838,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a) return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage); } - else if (isClassDeclaration(declaration)) { + else if (isClassLike(declaration)) { // still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} }) return !findAncestor(usage, n => isComputedPropertyName(n) && n.parent.parent === declaration); } @@ -13641,6 +13648,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } + // If the original mapped type had an intersection constraint we extract its components, + // and we make an attempt to do so even if the intersection has been reduced to a union. + // This entire process allows us to possibly retrieve the filtering type literals. + // e.g. { [K in keyof U & ("a" | "b") ] } -> "a" | "b" + function getLimitedConstraint(type: ReverseMappedType) { + const constraint = getConstraintTypeFromMappedType(type.mappedType); + if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) { + return; + } + const origin = (constraint.flags & TypeFlags.Union) ? (constraint as UnionType).origin : (constraint as IntersectionType); + if (!origin || !(origin.flags & TypeFlags.Intersection)) { + return; + } + const limitedConstraint = getIntersectionType((origin as IntersectionType).types.filter(t => t !== type.constraintType)); + return limitedConstraint !== neverType ? limitedConstraint : undefined; + } + function resolveReverseMappedTypeMembers(type: ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, stringType); const modifiers = getMappedTypeModifiers(type.mappedType); @@ -13648,7 +13672,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); + const limitedConstraint = getLimitedConstraint(type); for (const prop of getPropertiesOfType(type.source)) { + // In case of a reverse mapped type with an intersection constraint, if we were able to + // extract the filtering type literals we skip those properties that are not assignable to them, + // because the extra properties wouldn't get through the application of the mapped type anyway + if (limitedConstraint) { + const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); + if (!isTypeAssignableTo(propertyNameType, limitedConstraint)) { + continue; + } + } const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; inferredProp.declarations = prop.declarations; @@ -13741,7 +13775,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraintType = getConstraintTypeFromMappedType(type); const mappedType = (type.target as MappedType) || type; const nameType = getNameTypeFromMappedType(mappedType); - const shouldLinkPropDeclarations = !nameType || isFilteringMappedType(mappedType); + const shouldLinkPropDeclarations = getMappedTypeNameTypeKind(mappedType) !== MappedTypeNameTypeKind.Remapping; const templateType = getTemplateTypeFromMappedType(mappedType); const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateModifiers = getMappedTypeModifiers(type); @@ -13923,9 +13957,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function isFilteringMappedType(type: MappedType): boolean { + function getMappedTypeNameTypeKind(type: MappedType): MappedTypeNameTypeKind { const nameType = getNameTypeFromMappedType(type); - return !!nameType && isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type)); + if (!nameType) { + return MappedTypeNameTypeKind.None; + } + return isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type)) ? MappedTypeNameTypeKind.Filtering : MappedTypeNameTypeKind.Remapping; } function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { @@ -15043,6 +15080,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let flags = SignatureFlags.None; let minArgumentCount = 0; let thisParameter: Symbol | undefined; + let thisTag: JSDocThisTag | undefined = isInJSFile(declaration) ? getJSDocThisTag(declaration) : undefined; let hasThisParameter = false; const iife = getImmediatelyInvokedFunctionExpression(declaration); const isJSConstructSignature = isJSDocConstructSignature(declaration); @@ -15060,6 +15098,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // signature. for (let i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) { const param = declaration.parameters[i]; + if (isInJSFile(param) && isJSDocThisTag(param)) { + thisTag = param; + continue; + } let paramSymbol = param.symbol; const type = isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type; @@ -15103,11 +15145,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - if (isInJSFile(declaration)) { - const thisTag = getJSDocThisTag(declaration); - if (thisTag && thisTag.typeExpression) { - thisParameter = createSymbolWithType(createSymbol(SymbolFlags.FunctionScopedVariable, InternalSymbolName.This), getTypeFromTypeNode(thisTag.typeExpression)); - } + if (thisTag && thisTag.typeExpression) { + thisParameter = createSymbolWithType(createSymbol(SymbolFlags.FunctionScopedVariable, InternalSymbolName.This), getTypeFromTypeNode(thisTag.typeExpression)); } const hostDeclaration = isJSDocSignature(declaration) ? getEffectiveJSDocHost(declaration) : declaration; @@ -17700,7 +17739,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function shouldDeferIndexType(type: Type, indexFlags = IndexFlags.None) { return !!(type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) || - isGenericMappedType(type) && !hasDistributiveNameType(type) || + isGenericMappedType(type) && (!hasDistributiveNameType(type) || getMappedTypeNameTypeKind(type) === MappedTypeNameTypeKind.Remapping) || type.flags & TypeFlags.Union && !(indexFlags & IndexFlags.NoReducibleCheck) && isGenericReducibleType(type) || type.flags & TypeFlags.Intersection && maybeTypeOfKind(type, TypeFlags.Instantiable)); } @@ -18283,7 +18322,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // K is generic and N is assignable to P, instantiate E using a mapper that substitutes the index type for P. // For example, for an index access { [P in K]: Box }[X], we construct the type Box. if (isGenericMappedType(objectType)) { - if (!getNameTypeFromMappedType(objectType) || isFilteringMappedType(objectType)) { + if (getMappedTypeNameTypeKind(objectType) !== MappedTypeNameTypeKind.Remapping) { return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing)); } } @@ -20664,8 +20703,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // similar to return values, callback parameters are output positions. This means that a Promise, // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant) // with respect to T. - const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); - const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType)); + const sourceSig = checkMode & SignatureCheckMode.Callback || isInstantiatedGenericParameter(source, i) ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); + const targetSig = checkMode & SignatureCheckMode.Callback || isInstantiatedGenericParameter(target, i) ? undefined : getSingleCallSignature(getNonNullableType(targetType)); const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) && getTypeFacts(sourceType, TypeFacts.IsUndefinedOrNull) === getTypeFacts(targetType, TypeFacts.IsUndefinedOrNull); let related = callbacks ? @@ -25327,7 +25366,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { target = getIntersectionType(targets); } } - else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { + if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { target = getActualTypeVariable(target); } if (target.flags & TypeFlags.TypeVariable) { @@ -25668,9 +25707,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (constraintType.flags & TypeFlags.Index) { constraintType = getSimplifiedIndexType(constraintType as IndexType); } - if (constraintType.flags & TypeFlags.Union) { + if (constraintType.flags & TypeFlags.UnionOrIntersection) { let result = false; - for (const type of (constraintType as UnionType).types) { + for (const type of (constraintType as (UnionType | IntersectionType)).types) { result = inferToMappedType(source, target, type) || result; } return result; @@ -33462,6 +33501,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters); } + function isInstantiatedGenericParameter(signature: Signature, pos: number) { + let type; + return !!(signature.target && (type = tryGetTypeAtPosition(signature.target, pos)) && isGenericType(type)); + } + // If type has a single call signature and no other members, return that signature. Otherwise, return undefined. function getSingleCallSignature(type: Type): Signature | undefined { return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false); @@ -34752,7 +34796,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // use the resolvingSignature singleton to indicate that we deferred processing. This result will be // propagated out and eventually turned into silentNeverType (a type that is assignable to anything and // from which we never make inferences). - if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { + if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) { skippedGenericFunction(node, checkMode); return resolvingSignature; } @@ -34765,8 +34809,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunction(signature: Signature) { - return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); + function isGenericFunctionReturningFunctionOrConstructor(signature: Signature) { + if (!signature.typeParameters) { + return false; + } + const returnType = getReturnTypeOfSignature(signature); + return isFunctionType(returnType) || isConstructorType(returnType); } /** @@ -40120,7 +40168,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Check if the index type is assignable to 'keyof T' for the object type. const objectType = (type as IndexedAccessType).objectType; const indexType = (type as IndexedAccessType).indexType; - if (isTypeAssignableTo(indexType, getIndexType(objectType, IndexFlags.None))) { + // skip index type deferral on remapping mapped types + const objectIndexType = isGenericMappedType(objectType) && getMappedTypeNameTypeKind(objectType) === MappedTypeNameTypeKind.Remapping + ? getIndexTypeForMappedType(objectType, IndexFlags.None) + : getIndexType(objectType, IndexFlags.None); + if (isTypeAssignableTo(indexType, objectIndexType)) { if ( accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) && getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.IncludeReadonly diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fcf95696eb9..9da128e705a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9343,7 +9343,7 @@ namespace Parser { function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) { if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { const pos = getNodePos(); - let child: JSDocPropertyLikeTag | JSDocTypeTag | JSDocTemplateTag | false; + let child: JSDocPropertyLikeTag | JSDocTypeTag | JSDocTemplateTag | JSDocThisTag | false; let children: JSDocPropertyLikeTag[] | undefined; while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) { if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) { @@ -9635,7 +9635,7 @@ namespace Parser { return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false; } - function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | false { + function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { let canParseTag = true; let seenAsterisk = false; while (true) { @@ -9672,7 +9672,7 @@ namespace Parser { } } - function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | false { + function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { Debug.assert(token() === SyntaxKind.AtToken); const start = scanner.getTokenFullStart(); nextTokenJSDoc(); @@ -9694,6 +9694,8 @@ namespace Parser { break; case "template": return parseTemplateTag(start, tagName, indent, indentText); + case "this": + return parseThisTag(start, tagName, indent, indentText); default: return false; } diff --git a/src/lib/es2020.string.d.ts b/src/lib/es2020.string.d.ts index 1602ac7b10f..bc7cf1ad5f7 100644 --- a/src/lib/es2020.string.d.ts +++ b/src/lib/es2020.string.d.ts @@ -6,7 +6,7 @@ interface String { * containing the results of that search. * @param regexp A variable name or string literal containing the regular expression pattern and flags. */ - matchAll(regexp: RegExp): IterableIterator; + matchAll(regexp: RegExp): IterableIterator; /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */ toLocaleLowerCase(locales?: Intl.LocalesArgument): string; diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 9637387afa0..a15b48d8d74 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -36,6 +36,7 @@ export interface TranspileOptions { moduleName?: string; renamedDependencies?: MapLike; transformers?: CustomTransformers; + jsDocParsingMode?: JSDocParsingMode; } export interface TranspileOutput { @@ -121,7 +122,7 @@ export function transpileModule(input: string, transpileOptions: TranspileOption languageVersion: getEmitScriptTarget(options), impliedNodeFormat: getImpliedNodeFormatForFile(toPath(inputFileName, "", compilerHost.getCanonicalFileName), /*packageJsonInfoCache*/ undefined, compilerHost, options), setExternalModuleIndicator: getSetExternalModuleIndicator(options), - jsDocParsingMode: JSDocParsingMode.ParseNone, + jsDocParsingMode: transpileOptions.jsDocParsingMode ?? JSDocParsingMode.ParseAll, }, ); if (transpileOptions.moduleName) { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b051e45f608..a55b003f6c8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -11618,6 +11618,7 @@ declare namespace ts { moduleName?: string; renamedDependencies?: MapLike; transformers?: CustomTransformers; + jsDocParsingMode?: JSDocParsingMode; } interface TranspileOutput { outputText: string; diff --git a/tests/baselines/reference/callbackTag4.symbols b/tests/baselines/reference/callbackTag4.symbols new file mode 100644 index 00000000000..17c0d29004c --- /dev/null +++ b/tests/baselines/reference/callbackTag4.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/conformance/jsdoc/callbackTag4.ts] //// + +=== ./a.js === +/** + * @callback C + * @this {{ a: string, b: number }} + * @param {string} a + * @param {number} b + * @returns {boolean} + */ + +/** @type {C} */ +const cb = function (a, b) { +>cb : Symbol(cb, Decl(a.js, 9, 5)) +>a : Symbol(a, Decl(a.js, 9, 21)) +>b : Symbol(b, Decl(a.js, 9, 23)) + + this +>this : Symbol(this) + + return true +} + diff --git a/tests/baselines/reference/callbackTag4.types b/tests/baselines/reference/callbackTag4.types new file mode 100644 index 00000000000..1afbc752a07 --- /dev/null +++ b/tests/baselines/reference/callbackTag4.types @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/jsdoc/callbackTag4.ts] //// + +=== ./a.js === +/** + * @callback C + * @this {{ a: string, b: number }} + * @param {string} a + * @param {number} b + * @returns {boolean} + */ + +/** @type {C} */ +const cb = function (a, b) { +>cb : C +>function (a, b) { this return true} : (this: { a: string; b: number; }, a: string, b: number) => boolean +>a : string +>b : number + + this +>this : { a: string; b: number; } + + return true +>true : true +} + diff --git a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.errors.txt b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.errors.txt index ad9d57b5401..466c6664966 100644 --- a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.errors.txt @@ -1,25 +1,49 @@ -computedPropertyNamesWithStaticProperty.ts(3,10): error TS2449: Class 'C' used before its declaration. -computedPropertyNamesWithStaticProperty.ts(6,10): error TS2449: Class 'C' used before its declaration. -computedPropertyNamesWithStaticProperty.ts(9,6): error TS2449: Class 'C' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(3,10): error TS2449: Class 'C1' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(6,10): error TS2449: Class 'C1' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(9,6): error TS2449: Class 'C1' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(14,10): error TS2449: Class 'C2' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(17,10): error TS2449: Class 'C2' used before its declaration. +computedPropertyNamesWithStaticProperty.ts(20,6): error TS2449: Class 'C2' used before its declaration. -==== computedPropertyNamesWithStaticProperty.ts (3 errors) ==== - class C { +==== computedPropertyNamesWithStaticProperty.ts (6 errors) ==== + class C1 { static staticProp = 10; - get [C.staticProp]() { - ~ -!!! error TS2449: Class 'C' used before its declaration. -!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here. + get [C1.staticProp]() { + ~~ +!!! error TS2449: Class 'C1' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C1' is declared here. return "hello"; } - set [C.staticProp](x: string) { - ~ -!!! error TS2449: Class 'C' used before its declaration. -!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here. + set [C1.staticProp](x: string) { + ~~ +!!! error TS2449: Class 'C1' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C1' is declared here. var y = x; } - [C.staticProp]() { } - ~ -!!! error TS2449: Class 'C' used before its declaration. -!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here. - } \ No newline at end of file + [C1.staticProp]() { } + ~~ +!!! error TS2449: Class 'C1' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:1:7: 'C1' is declared here. + } + + (class C2 { + static staticProp = 10; + get [C2.staticProp]() { + ~~ +!!! error TS2449: Class 'C2' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:12:8: 'C2' is declared here. + return "hello"; + } + set [C2.staticProp](x: string) { + ~~ +!!! error TS2449: Class 'C2' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:12:8: 'C2' is declared here. + var y = x; + } + [C2.staticProp]() { } + ~~ +!!! error TS2449: Class 'C2' used before its declaration. +!!! related TS2728 computedPropertyNamesWithStaticProperty.ts:12:8: 'C2' is declared here. + }) + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.js b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.js index aaface52b35..63068159d90 100644 --- a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.js +++ b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.js @@ -1,25 +1,49 @@ //// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts] //// //// [computedPropertyNamesWithStaticProperty.ts] -class C { +class C1 { static staticProp = 10; - get [C.staticProp]() { + get [C1.staticProp]() { return "hello"; } - set [C.staticProp](x: string) { + set [C1.staticProp](x: string) { var y = x; } - [C.staticProp]() { } -} + [C1.staticProp]() { } +} + +(class C2 { + static staticProp = 10; + get [C2.staticProp]() { + return "hello"; + } + set [C2.staticProp](x: string) { + var y = x; + } + [C2.staticProp]() { } +}) + //// [computedPropertyNamesWithStaticProperty.js] -class C { - get [C.staticProp]() { +var _a; +class C1 { + get [C1.staticProp]() { return "hello"; } - set [C.staticProp](x) { + set [C1.staticProp](x) { var y = x; } - [C.staticProp]() { } + [C1.staticProp]() { } } -C.staticProp = 10; +C1.staticProp = 10; +(_a = class C2 { + get [C2.staticProp]() { + return "hello"; + } + set [C2.staticProp](x) { + var y = x; + } + [C2.staticProp]() { } + }, + _a.staticProp = 10, + _a); diff --git a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.symbols b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.symbols index 3b6b3d1aeb0..42410e531eb 100644 --- a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.symbols +++ b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.symbols @@ -1,34 +1,68 @@ //// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts] //// === computedPropertyNamesWithStaticProperty.ts === -class C { ->C : Symbol(C, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) +class C1 { +>C1 : Symbol(C1, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) static staticProp = 10; ->staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) +>staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) - get [C.staticProp]() { ->[C.staticProp] : Symbol(C[C.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 1, 27)) ->C.staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) ->C : Symbol(C, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) ->staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) + get [C1.staticProp]() { +>[C1.staticProp] : Symbol(C1[C1.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 1, 27)) +>C1.staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) +>C1 : Symbol(C1, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) +>staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) return "hello"; } - set [C.staticProp](x: string) { ->[C.staticProp] : Symbol(C[C.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 4, 5)) ->C.staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) ->C : Symbol(C, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) ->staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) ->x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 5, 23)) + set [C1.staticProp](x: string) { +>[C1.staticProp] : Symbol(C1[C1.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 4, 5)) +>C1.staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) +>C1 : Symbol(C1, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) +>staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) +>x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 5, 24)) var y = x; >y : Symbol(y, Decl(computedPropertyNamesWithStaticProperty.ts, 6, 11)) ->x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 5, 23)) +>x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 5, 24)) } - [C.staticProp]() { } ->[C.staticProp] : Symbol(C[C.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 7, 5)) ->C.staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) ->C : Symbol(C, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) ->staticProp : Symbol(C.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 9)) + [C1.staticProp]() { } +>[C1.staticProp] : Symbol(C1[C1.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 7, 5)) +>C1.staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) +>C1 : Symbol(C1, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 0)) +>staticProp : Symbol(C1.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 0, 10)) } + +(class C2 { +>C2 : Symbol(C2, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 1)) + + static staticProp = 10; +>staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) + + get [C2.staticProp]() { +>[C2.staticProp] : Symbol(C2[C2.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 12, 27)) +>C2.staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) +>C2 : Symbol(C2, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 1)) +>staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) + + return "hello"; + } + set [C2.staticProp](x: string) { +>[C2.staticProp] : Symbol(C2[C2.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 15, 5)) +>C2.staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) +>C2 : Symbol(C2, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 1)) +>staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) +>x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 16, 24)) + + var y = x; +>y : Symbol(y, Decl(computedPropertyNamesWithStaticProperty.ts, 17, 11)) +>x : Symbol(x, Decl(computedPropertyNamesWithStaticProperty.ts, 16, 24)) + } + [C2.staticProp]() { } +>[C2.staticProp] : Symbol(C2[C2.staticProp], Decl(computedPropertyNamesWithStaticProperty.ts, 18, 5)) +>C2.staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) +>C2 : Symbol(C2, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 1)) +>staticProp : Symbol(C2.staticProp, Decl(computedPropertyNamesWithStaticProperty.ts, 11, 11)) + +}) + diff --git a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.types b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.types index f4707536a6a..00d4cdf9e21 100644 --- a/tests/baselines/reference/computedPropertyNamesWithStaticProperty.types +++ b/tests/baselines/reference/computedPropertyNamesWithStaticProperty.types @@ -1,26 +1,26 @@ //// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts] //// === computedPropertyNamesWithStaticProperty.ts === -class C { ->C : C +class C1 { +>C1 : C1 static staticProp = 10; >staticProp : number >10 : 10 - get [C.staticProp]() { ->[C.staticProp] : string ->C.staticProp : number ->C : typeof C + get [C1.staticProp]() { +>[C1.staticProp] : string +>C1.staticProp : number +>C1 : typeof C1 >staticProp : number return "hello"; >"hello" : "hello" } - set [C.staticProp](x: string) { ->[C.staticProp] : string ->C.staticProp : number ->C : typeof C + set [C1.staticProp](x: string) { +>[C1.staticProp] : string +>C1.staticProp : number +>C1 : typeof C1 >staticProp : number >x : string @@ -28,9 +28,47 @@ class C { >y : string >x : string } - [C.staticProp]() { } ->[C.staticProp] : () => void ->C.staticProp : number ->C : typeof C + [C1.staticProp]() { } +>[C1.staticProp] : () => void +>C1.staticProp : number +>C1 : typeof C1 >staticProp : number } + +(class C2 { +>(class C2 { static staticProp = 10; get [C2.staticProp]() { return "hello"; } set [C2.staticProp](x: string) { var y = x; } [C2.staticProp]() { }}) : typeof C2 +>class C2 { static staticProp = 10; get [C2.staticProp]() { return "hello"; } set [C2.staticProp](x: string) { var y = x; } [C2.staticProp]() { }} : typeof C2 +>C2 : typeof C2 + + static staticProp = 10; +>staticProp : number +>10 : 10 + + get [C2.staticProp]() { +>[C2.staticProp] : string +>C2.staticProp : number +>C2 : typeof C2 +>staticProp : number + + return "hello"; +>"hello" : "hello" + } + set [C2.staticProp](x: string) { +>[C2.staticProp] : string +>C2.staticProp : number +>C2 : typeof C2 +>staticProp : number +>x : string + + var y = x; +>y : string +>x : string + } + [C2.staticProp]() { } +>[C2.staticProp] : () => void +>C2.staticProp : number +>C2 : typeof C2 +>staticProp : number + +}) + diff --git a/tests/baselines/reference/covariantCallbacks.errors.txt b/tests/baselines/reference/covariantCallbacks.errors.txt index 5de161c1ab5..7a9e34234fc 100644 --- a/tests/baselines/reference/covariantCallbacks.errors.txt +++ b/tests/baselines/reference/covariantCallbacks.errors.txt @@ -23,9 +23,18 @@ covariantCallbacks.ts(69,5): error TS2322: Type 'AList4' is not assignable to ty Types of parameters 'cb' and 'cb' are incompatible. Types of parameters 'item' and 'item' are incompatible. Type 'A' is not assignable to type 'B'. +covariantCallbacks.ts(98,1): error TS2322: Type 'SetLike1<(x: string) => void>' is not assignable to type 'SetLike1<(x: unknown) => void>'. + Type '(x: string) => void' is not assignable to type '(x: unknown) => void'. + Types of parameters 'x' and 'x' are incompatible. + Type 'unknown' is not assignable to type 'string'. +covariantCallbacks.ts(106,1): error TS2322: Type 'SetLike2<(x: string) => void>' is not assignable to type 'SetLike1<(x: unknown) => void>'. + The types returned by 'get()' are incompatible between these types. + Type '(x: string) => void' is not assignable to type '(x: unknown) => void'. + Types of parameters 'x' and 'x' are incompatible. + Type 'unknown' is not assignable to type 'string'. -==== covariantCallbacks.ts (6 errors) ==== +==== covariantCallbacks.ts (8 errors) ==== // Test that callback parameters are related covariantly interface P { @@ -128,4 +137,52 @@ covariantCallbacks.ts(69,5): error TS2322: Type 'AList4' is not assignable to ty !!! error TS2322: Types of parameters 'item' and 'item' are incompatible. !!! error TS2322: Type 'A' is not assignable to type 'B'. } + + // Repro from #51620 + + type Bivar = { set(value: T): void } + + declare let bu: Bivar; + declare let bs: Bivar; + bu = bs; + bs = bu; + + declare let bfu: Bivar<(x: unknown) => void>; + declare let bfs: Bivar<(x: string) => void>; + bfu = bfs; + bfs = bfu; + + type Bivar1 = { set(value: T): void } + type Bivar2 = { set(value: T): void } + + declare let b1fu: Bivar1<(x: unknown) => void>; + declare let b2fs: Bivar2<(x: string) => void>; + b1fu = b2fs; + b2fs = b1fu; + + type SetLike = { set(value: T): void, get(): T } + + declare let sx: SetLike1<(x: unknown) => void>; + declare let sy: SetLike1<(x: string) => void>; + sx = sy; // Error + ~~ +!!! error TS2322: Type 'SetLike1<(x: string) => void>' is not assignable to type 'SetLike1<(x: unknown) => void>'. +!!! error TS2322: Type '(x: string) => void' is not assignable to type '(x: unknown) => void'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + sy = sx; + + type SetLike1 = { set(value: T): void, get(): T } + type SetLike2 = { set(value: T): void, get(): T } + + declare let s1: SetLike1<(x: unknown) => void>; + declare let s2: SetLike2<(x: string) => void>; + s1 = s2; // Error + ~~ +!!! error TS2322: Type 'SetLike2<(x: string) => void>' is not assignable to type 'SetLike1<(x: unknown) => void>'. +!!! error TS2322: The types returned by 'get()' are incompatible between these types. +!!! error TS2322: Type '(x: string) => void' is not assignable to type '(x: unknown) => void'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + s2 = s1; \ No newline at end of file diff --git a/tests/baselines/reference/covariantCallbacks.js b/tests/baselines/reference/covariantCallbacks.js index 38578f1af5c..226e7d3ab55 100644 --- a/tests/baselines/reference/covariantCallbacks.js +++ b/tests/baselines/reference/covariantCallbacks.js @@ -71,6 +71,43 @@ function f14(a: AList4, b: BList4) { a = b; b = a; // Error } + +// Repro from #51620 + +type Bivar = { set(value: T): void } + +declare let bu: Bivar; +declare let bs: Bivar; +bu = bs; +bs = bu; + +declare let bfu: Bivar<(x: unknown) => void>; +declare let bfs: Bivar<(x: string) => void>; +bfu = bfs; +bfs = bfu; + +type Bivar1 = { set(value: T): void } +type Bivar2 = { set(value: T): void } + +declare let b1fu: Bivar1<(x: unknown) => void>; +declare let b2fs: Bivar2<(x: string) => void>; +b1fu = b2fs; +b2fs = b1fu; + +type SetLike = { set(value: T): void, get(): T } + +declare let sx: SetLike1<(x: unknown) => void>; +declare let sy: SetLike1<(x: string) => void>; +sx = sy; // Error +sy = sx; + +type SetLike1 = { set(value: T): void, get(): T } +type SetLike2 = { set(value: T): void, get(): T } + +declare let s1: SetLike1<(x: unknown) => void>; +declare let s2: SetLike2<(x: string) => void>; +s1 = s2; // Error +s2 = s1; //// [covariantCallbacks.js] @@ -101,3 +138,13 @@ function f14(a, b) { a = b; b = a; // Error } +bu = bs; +bs = bu; +bfu = bfs; +bfs = bfu; +b1fu = b2fs; +b2fs = b1fu; +sx = sy; // Error +sy = sx; +s1 = s2; // Error +s2 = s1; diff --git a/tests/baselines/reference/covariantCallbacks.symbols b/tests/baselines/reference/covariantCallbacks.symbols index c710196e50b..ca168fca246 100644 --- a/tests/baselines/reference/covariantCallbacks.symbols +++ b/tests/baselines/reference/covariantCallbacks.symbols @@ -207,3 +207,141 @@ function f14(a: AList4, b: BList4) { >a : Symbol(a, Decl(covariantCallbacks.ts, 66, 13)) } +// Repro from #51620 + +type Bivar = { set(value: T): void } +>Bivar : Symbol(Bivar, Decl(covariantCallbacks.ts, 69, 1)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 73, 11)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 73, 17)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 73, 22)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 73, 11)) + +declare let bu: Bivar; +>bu : Symbol(bu, Decl(covariantCallbacks.ts, 75, 11)) +>Bivar : Symbol(Bivar, Decl(covariantCallbacks.ts, 69, 1)) + +declare let bs: Bivar; +>bs : Symbol(bs, Decl(covariantCallbacks.ts, 76, 11)) +>Bivar : Symbol(Bivar, Decl(covariantCallbacks.ts, 69, 1)) + +bu = bs; +>bu : Symbol(bu, Decl(covariantCallbacks.ts, 75, 11)) +>bs : Symbol(bs, Decl(covariantCallbacks.ts, 76, 11)) + +bs = bu; +>bs : Symbol(bs, Decl(covariantCallbacks.ts, 76, 11)) +>bu : Symbol(bu, Decl(covariantCallbacks.ts, 75, 11)) + +declare let bfu: Bivar<(x: unknown) => void>; +>bfu : Symbol(bfu, Decl(covariantCallbacks.ts, 80, 11)) +>Bivar : Symbol(Bivar, Decl(covariantCallbacks.ts, 69, 1)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 80, 24)) + +declare let bfs: Bivar<(x: string) => void>; +>bfs : Symbol(bfs, Decl(covariantCallbacks.ts, 81, 11)) +>Bivar : Symbol(Bivar, Decl(covariantCallbacks.ts, 69, 1)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 81, 24)) + +bfu = bfs; +>bfu : Symbol(bfu, Decl(covariantCallbacks.ts, 80, 11)) +>bfs : Symbol(bfs, Decl(covariantCallbacks.ts, 81, 11)) + +bfs = bfu; +>bfs : Symbol(bfs, Decl(covariantCallbacks.ts, 81, 11)) +>bfu : Symbol(bfu, Decl(covariantCallbacks.ts, 80, 11)) + +type Bivar1 = { set(value: T): void } +>Bivar1 : Symbol(Bivar1, Decl(covariantCallbacks.ts, 83, 10)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 85, 12)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 85, 18)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 85, 23)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 85, 12)) + +type Bivar2 = { set(value: T): void } +>Bivar2 : Symbol(Bivar2, Decl(covariantCallbacks.ts, 85, 40)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 86, 12)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 86, 18)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 86, 23)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 86, 12)) + +declare let b1fu: Bivar1<(x: unknown) => void>; +>b1fu : Symbol(b1fu, Decl(covariantCallbacks.ts, 88, 11)) +>Bivar1 : Symbol(Bivar1, Decl(covariantCallbacks.ts, 83, 10)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 88, 26)) + +declare let b2fs: Bivar2<(x: string) => void>; +>b2fs : Symbol(b2fs, Decl(covariantCallbacks.ts, 89, 11)) +>Bivar2 : Symbol(Bivar2, Decl(covariantCallbacks.ts, 85, 40)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 89, 26)) + +b1fu = b2fs; +>b1fu : Symbol(b1fu, Decl(covariantCallbacks.ts, 88, 11)) +>b2fs : Symbol(b2fs, Decl(covariantCallbacks.ts, 89, 11)) + +b2fs = b1fu; +>b2fs : Symbol(b2fs, Decl(covariantCallbacks.ts, 89, 11)) +>b1fu : Symbol(b1fu, Decl(covariantCallbacks.ts, 88, 11)) + +type SetLike = { set(value: T): void, get(): T } +>SetLike : Symbol(SetLike, Decl(covariantCallbacks.ts, 91, 12)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 93, 13)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 93, 19)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 93, 24)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 93, 13)) +>get : Symbol(get, Decl(covariantCallbacks.ts, 93, 40)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 93, 13)) + +declare let sx: SetLike1<(x: unknown) => void>; +>sx : Symbol(sx, Decl(covariantCallbacks.ts, 95, 11)) +>SetLike1 : Symbol(SetLike1, Decl(covariantCallbacks.ts, 98, 8)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 95, 26)) + +declare let sy: SetLike1<(x: string) => void>; +>sy : Symbol(sy, Decl(covariantCallbacks.ts, 96, 11)) +>SetLike1 : Symbol(SetLike1, Decl(covariantCallbacks.ts, 98, 8)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 96, 26)) + +sx = sy; // Error +>sx : Symbol(sx, Decl(covariantCallbacks.ts, 95, 11)) +>sy : Symbol(sy, Decl(covariantCallbacks.ts, 96, 11)) + +sy = sx; +>sy : Symbol(sy, Decl(covariantCallbacks.ts, 96, 11)) +>sx : Symbol(sx, Decl(covariantCallbacks.ts, 95, 11)) + +type SetLike1 = { set(value: T): void, get(): T } +>SetLike1 : Symbol(SetLike1, Decl(covariantCallbacks.ts, 98, 8)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 100, 14)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 100, 20)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 100, 25)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 100, 14)) +>get : Symbol(get, Decl(covariantCallbacks.ts, 100, 41)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 100, 14)) + +type SetLike2 = { set(value: T): void, get(): T } +>SetLike2 : Symbol(SetLike2, Decl(covariantCallbacks.ts, 100, 52)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 101, 14)) +>set : Symbol(set, Decl(covariantCallbacks.ts, 101, 20)) +>value : Symbol(value, Decl(covariantCallbacks.ts, 101, 25)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 101, 14)) +>get : Symbol(get, Decl(covariantCallbacks.ts, 101, 41)) +>T : Symbol(T, Decl(covariantCallbacks.ts, 101, 14)) + +declare let s1: SetLike1<(x: unknown) => void>; +>s1 : Symbol(s1, Decl(covariantCallbacks.ts, 103, 11)) +>SetLike1 : Symbol(SetLike1, Decl(covariantCallbacks.ts, 98, 8)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 103, 26)) + +declare let s2: SetLike2<(x: string) => void>; +>s2 : Symbol(s2, Decl(covariantCallbacks.ts, 104, 11)) +>SetLike2 : Symbol(SetLike2, Decl(covariantCallbacks.ts, 100, 52)) +>x : Symbol(x, Decl(covariantCallbacks.ts, 104, 26)) + +s1 = s2; // Error +>s1 : Symbol(s1, Decl(covariantCallbacks.ts, 103, 11)) +>s2 : Symbol(s2, Decl(covariantCallbacks.ts, 104, 11)) + +s2 = s1; +>s2 : Symbol(s2, Decl(covariantCallbacks.ts, 104, 11)) +>s1 : Symbol(s1, Decl(covariantCallbacks.ts, 103, 11)) + diff --git a/tests/baselines/reference/covariantCallbacks.types b/tests/baselines/reference/covariantCallbacks.types index 1b2f082da52..849ff661417 100644 --- a/tests/baselines/reference/covariantCallbacks.types +++ b/tests/baselines/reference/covariantCallbacks.types @@ -170,3 +170,126 @@ function f14(a: AList4, b: BList4) { >a : AList4 } +// Repro from #51620 + +type Bivar = { set(value: T): void } +>Bivar : Bivar +>set : (value: T) => void +>value : T + +declare let bu: Bivar; +>bu : Bivar + +declare let bs: Bivar; +>bs : Bivar + +bu = bs; +>bu = bs : Bivar +>bu : Bivar +>bs : Bivar + +bs = bu; +>bs = bu : Bivar +>bs : Bivar +>bu : Bivar + +declare let bfu: Bivar<(x: unknown) => void>; +>bfu : Bivar<(x: unknown) => void> +>x : unknown + +declare let bfs: Bivar<(x: string) => void>; +>bfs : Bivar<(x: string) => void> +>x : string + +bfu = bfs; +>bfu = bfs : Bivar<(x: string) => void> +>bfu : Bivar<(x: unknown) => void> +>bfs : Bivar<(x: string) => void> + +bfs = bfu; +>bfs = bfu : Bivar<(x: unknown) => void> +>bfs : Bivar<(x: string) => void> +>bfu : Bivar<(x: unknown) => void> + +type Bivar1 = { set(value: T): void } +>Bivar1 : Bivar1 +>set : (value: T) => void +>value : T + +type Bivar2 = { set(value: T): void } +>Bivar2 : Bivar2 +>set : (value: T) => void +>value : T + +declare let b1fu: Bivar1<(x: unknown) => void>; +>b1fu : Bivar1<(x: unknown) => void> +>x : unknown + +declare let b2fs: Bivar2<(x: string) => void>; +>b2fs : Bivar2<(x: string) => void> +>x : string + +b1fu = b2fs; +>b1fu = b2fs : Bivar2<(x: string) => void> +>b1fu : Bivar1<(x: unknown) => void> +>b2fs : Bivar2<(x: string) => void> + +b2fs = b1fu; +>b2fs = b1fu : Bivar1<(x: unknown) => void> +>b2fs : Bivar2<(x: string) => void> +>b1fu : Bivar1<(x: unknown) => void> + +type SetLike = { set(value: T): void, get(): T } +>SetLike : SetLike +>set : (value: T) => void +>value : T +>get : () => T + +declare let sx: SetLike1<(x: unknown) => void>; +>sx : SetLike1<(x: unknown) => void> +>x : unknown + +declare let sy: SetLike1<(x: string) => void>; +>sy : SetLike1<(x: string) => void> +>x : string + +sx = sy; // Error +>sx = sy : SetLike1<(x: string) => void> +>sx : SetLike1<(x: unknown) => void> +>sy : SetLike1<(x: string) => void> + +sy = sx; +>sy = sx : SetLike1<(x: unknown) => void> +>sy : SetLike1<(x: string) => void> +>sx : SetLike1<(x: unknown) => void> + +type SetLike1 = { set(value: T): void, get(): T } +>SetLike1 : SetLike1 +>set : (value: T) => void +>value : T +>get : () => T + +type SetLike2 = { set(value: T): void, get(): T } +>SetLike2 : SetLike2 +>set : (value: T) => void +>value : T +>get : () => T + +declare let s1: SetLike1<(x: unknown) => void>; +>s1 : SetLike1<(x: unknown) => void> +>x : unknown + +declare let s2: SetLike2<(x: string) => void>; +>s2 : SetLike2<(x: string) => void> +>x : string + +s1 = s2; // Error +>s1 = s2 : SetLike2<(x: string) => void> +>s1 : SetLike1<(x: unknown) => void> +>s2 : SetLike2<(x: string) => void> + +s2 = s1; +>s2 = s1 : SetLike1<(x: unknown) => void> +>s2 : SetLike2<(x: string) => void> +>s1 : SetLike1<(x: unknown) => void> + diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt index 6e9abea9199..5fd2927b274 100644 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt @@ -1,6 +1,7 @@ genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'. Types of parameters 'a1' and 'x' are incompatible. - Type 'boolean' is not assignable to type 'string'. + Type '(a: string) => boolean' is not assignable to type '(y: string) => string'. + Type 'boolean' is not assignable to type 'string'. genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'. Type 'number' is not assignable to type '(n: Object) => 1'. @@ -41,7 +42,8 @@ genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of t ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'. !!! error TS2345: Types of parameters 'a1' and 'x' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. +!!! error TS2345: Type '(a: string) => boolean' is not assignable to type '(y: string) => string'. +!!! error TS2345: Type 'boolean' is not assignable to type 'string'. var r12 = foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2); // error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'. diff --git a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols new file mode 100644 index 00000000000..03e0bcb9f16 --- /dev/null +++ b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols @@ -0,0 +1,72 @@ +//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] //// + +=== inferenceGenericNestedCallReturningConstructor.ts === +interface Action { +>Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17)) + + new (ctx: TContext): void; +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 1, 7)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17)) +} + +declare class AssignAction { +>AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27)) + + constructor(ctx: TContext); +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 5, 14)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27)) +} + +declare function assign( +>assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) + + assigner: (ctx: TContext) => void +>assigner : Symbol(assigner, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 34)) +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 9, 13)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) + +): { + new (ctx: TContext): AssignAction; +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 11, 7)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) +>AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) +} + +declare function createMachine(config: { +>createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) +>config : Symbol(config, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 41)) + + context: TContext; +>context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 50)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) + + entry: Action; +>entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 15, 20)) +>Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0)) +>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) + +}): void; + +createMachine({ +>createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1)) + + context: { count: 0 }, +>context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 19, 15)) +>count : Symbol(count, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 12)) + + entry: assign((ctx) => { +>entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 24)) +>assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1)) +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17)) + + ctx // { count: number } +>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17)) + + }), +}); + diff --git a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types new file mode 100644 index 00000000000..ce6d09b4d32 --- /dev/null +++ b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types @@ -0,0 +1,63 @@ +//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] //// + +=== inferenceGenericNestedCallReturningConstructor.ts === +interface Action { + new (ctx: TContext): void; +>ctx : TContext +} + +declare class AssignAction { +>AssignAction : AssignAction + + constructor(ctx: TContext); +>ctx : TContext +} + +declare function assign( +>assign : (assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction + + assigner: (ctx: TContext) => void +>assigner : (ctx: TContext) => void +>ctx : TContext + +): { + new (ctx: TContext): AssignAction; +>ctx : TContext +} + +declare function createMachine(config: { +>createMachine : (config: { context: TContext; entry: Action;}) => void +>config : { context: TContext; entry: Action; } + + context: TContext; +>context : TContext + + entry: Action; +>entry : Action + +}): void; + +createMachine({ +>createMachine({ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),}) : void +>createMachine : (config: { context: TContext; entry: Action; }) => void +>{ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),} : { context: { count: number; }; entry: new (ctx: { count: number; }) => AssignAction<{ count: number; }>; } + + context: { count: 0 }, +>context : { count: number; } +>{ count: 0 } : { count: number; } +>count : number +>0 : 0 + + entry: assign((ctx) => { +>entry : new (ctx: { count: number; }) => AssignAction<{ count: number; }> +>assign((ctx) => { ctx // { count: number } }) : new (ctx: { count: number; }) => AssignAction<{ count: number; }> +>assign : (assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction +>(ctx) => { ctx // { count: number } } : (ctx: { count: number; }) => void +>ctx : { count: number; } + + ctx // { count: number } +>ctx : { count: number; } + + }), +}); + diff --git a/tests/baselines/reference/mappedTypeAsClauses.errors.txt b/tests/baselines/reference/mappedTypeAsClauses.errors.txt index 5f59683d955..2a8538e6860 100644 --- a/tests/baselines/reference/mappedTypeAsClauses.errors.txt +++ b/tests/baselines/reference/mappedTypeAsClauses.errors.txt @@ -1,4 +1,4 @@ -mappedTypeAsClauses.ts(130,3): error TS2345: Argument of type '"a"' is not assignable to parameter of type '"b"'. +mappedTypeAsClauses.ts(131,3): error TS2345: Argument of type '"a"' is not assignable to parameter of type '"b"'. ==== mappedTypeAsClauses.ts (1 errors) ==== @@ -30,7 +30,8 @@ mappedTypeAsClauses.ts(130,3): error TS2345: Argument of type '"a"' is not assig type DoubleProp = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] } type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number } type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' - type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` + type TD3 = keyof DoubleProp; // keyof DoubleProp + type TD4 = TD3<{ a: string, b: number }>; // 'a1' | 'a2' | 'b1' | 'b2' // Repro from #40619 @@ -155,4 +156,27 @@ mappedTypeAsClauses.ts(130,3): error TS2345: Argument of type '"a"' is not assig type TN3 = keyof { [P in keyof T as Exclude, 'b'>, 'a'>]: string }; type TN4 = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string }; type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string }; + + // repro from https://github.com/microsoft/TypeScript/issues/55129 + type Fruit = + | { + name: "apple"; + color: "red"; + } + | { + name: "banana"; + color: "yellow"; + } + | { + name: "orange"; + color: "orange"; + }; + type Result1 = { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown + }; + type Result2 = keyof { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown + } + type Test1 = keyof Result1 // "apple:red" | "banana:yellow" | "orange:orange" + type Test2 = Result2 // "apple:red" | "banana:yellow" | "orange:orange" \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeAsClauses.js b/tests/baselines/reference/mappedTypeAsClauses.js index be8cfd61431..9f401c2f1ce 100644 --- a/tests/baselines/reference/mappedTypeAsClauses.js +++ b/tests/baselines/reference/mappedTypeAsClauses.js @@ -29,7 +29,8 @@ type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | numbe type DoubleProp = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] } type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number } type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' -type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` +type TD3 = keyof DoubleProp; // keyof DoubleProp +type TD4 = TD3<{ a: string, b: number }>; // 'a1' | 'a2' | 'b1' | 'b2' // Repro from #40619 @@ -152,6 +153,29 @@ type TN2 = keyof { [P in keyof T as 'a' extends P ? 'x' : 'y']: string }; type TN3 = keyof { [P in keyof T as Exclude, 'b'>, 'a'>]: string }; type TN4 = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string }; type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string }; + +// repro from https://github.com/microsoft/TypeScript/issues/55129 +type Fruit = + | { + name: "apple"; + color: "red"; + } + | { + name: "banana"; + color: "yellow"; + } + | { + name: "orange"; + color: "orange"; + }; +type Result1 = { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +}; +type Result2 = keyof { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +} +type Test1 = keyof Result1 // "apple:red" | "banana:yellow" | "orange:orange" +type Test2 = Result2 // "apple:red" | "banana:yellow" | "orange:orange" //// [mappedTypeAsClauses.js] @@ -217,6 +241,10 @@ type TD1 = DoubleProp<{ }>; type TD2 = keyof TD1; type TD3 = keyof DoubleProp; +type TD4 = TD3<{ + a: string; + b: number; +}>; type Lazyify = { [K in keyof T as `get${Capitalize}`]: () => T[K]; }; @@ -337,3 +365,27 @@ type TN5 = keyof { [P in K as T[P] extends U ? K : never]: true; }]: string; }; +type Fruit = { + name: "apple"; + color: "red"; +} | { + name: "banana"; + color: "yellow"; +} | { + name: "orange"; + color: "orange"; +}; +type Result1 = { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown; +}; +type Result2 = keyof { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown; +}; +type Test1 = keyof Result1; +type Test2 = Result2; diff --git a/tests/baselines/reference/mappedTypeAsClauses.symbols b/tests/baselines/reference/mappedTypeAsClauses.symbols index 6028775c7b3..ebb570f319e 100644 --- a/tests/baselines/reference/mappedTypeAsClauses.symbols +++ b/tests/baselines/reference/mappedTypeAsClauses.symbols @@ -105,440 +105,507 @@ type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' >TD2 : Symbol(TD2, Decl(mappedTypeAsClauses.ts, 26, 48)) >TD1 : Symbol(TD1, Decl(mappedTypeAsClauses.ts, 25, 75)) -type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` +type TD3 = keyof DoubleProp; // keyof DoubleProp >TD3 : Symbol(TD3, Decl(mappedTypeAsClauses.ts, 27, 21)) >U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9)) >DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85)) >U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9)) +type TD4 = TD3<{ a: string, b: number }>; // 'a1' | 'a2' | 'b1' | 'b2' +>TD4 : Symbol(TD4, Decl(mappedTypeAsClauses.ts, 28, 34)) +>TD3 : Symbol(TD3, Decl(mappedTypeAsClauses.ts, 27, 21)) +>a : Symbol(a, Decl(mappedTypeAsClauses.ts, 29, 16)) +>b : Symbol(b, Decl(mappedTypeAsClauses.ts, 29, 27)) + // Repro from #40619 type Lazyify = { ->Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13)) +>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 29, 41)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 33, 13)) [K in keyof T as `get${Capitalize}`]: () => T[K] ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 34, 5)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 33, 13)) >Capitalize : Symbol(Capitalize, Decl(lib.es5.d.ts, --, --)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 34, 5)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 33, 13)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 34, 5)) }; interface Person { ->Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2)) +>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 35, 2)) readonly name: string; ->name : Symbol(Person.name, Decl(mappedTypeAsClauses.ts, 36, 18)) +>name : Symbol(Person.name, Decl(mappedTypeAsClauses.ts, 37, 18)) age: number; ->age : Symbol(Person.age, Decl(mappedTypeAsClauses.ts, 37, 26)) +>age : Symbol(Person.age, Decl(mappedTypeAsClauses.ts, 38, 26)) location?: string; ->location : Symbol(Person.location, Decl(mappedTypeAsClauses.ts, 38, 16)) +>location : Symbol(Person.location, Decl(mappedTypeAsClauses.ts, 39, 16)) } type LazyPerson = Lazyify; ->LazyPerson : Symbol(LazyPerson, Decl(mappedTypeAsClauses.ts, 40, 1)) ->Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34)) ->Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2)) +>LazyPerson : Symbol(LazyPerson, Decl(mappedTypeAsClauses.ts, 41, 1)) +>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 29, 41)) +>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 35, 2)) // Repro from #40833 type Example = {foo: string, bar: number}; ->Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 42, 34)) ->foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 46, 16)) ->bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 46, 28)) +>Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 43, 34)) +>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 47, 16)) +>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 47, 28)) type PickByValueType = { ->PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 46, 42)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 48, 23)) +>PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 47, 42)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 49, 21)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 49, 23)) [K in keyof T as T[K] extends U ? K : never]: T[K] ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 48, 23)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 50, 3)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 49, 21)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 49, 21)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 50, 3)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 49, 23)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 50, 3)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 49, 21)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 50, 3)) }; type T1 = PickByValueType; ->T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2)) ->PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 46, 42)) ->Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 42, 34)) +>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 51, 2)) +>PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 47, 42)) +>Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 43, 34)) const e1: T1 = { ->e1 : Symbol(e1, Decl(mappedTypeAsClauses.ts, 53, 5)) ->T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2)) +>e1 : Symbol(e1, Decl(mappedTypeAsClauses.ts, 54, 5)) +>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 51, 2)) foo: "hello" ->foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 53, 16)) +>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 54, 16)) }; type T2 = keyof T1; ->T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 55, 2)) ->T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2)) +>T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 56, 2)) +>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 51, 2)) const e2: T2 = "foo"; ->e2 : Symbol(e2, Decl(mappedTypeAsClauses.ts, 57, 5)) ->T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 55, 2)) +>e2 : Symbol(e2, Decl(mappedTypeAsClauses.ts, 58, 5)) +>T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 56, 2)) // Repro from #41133 interface Car { ->Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21)) +>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 58, 21)) name: string; ->name : Symbol(Car.name, Decl(mappedTypeAsClauses.ts, 61, 15)) +>name : Symbol(Car.name, Decl(mappedTypeAsClauses.ts, 62, 15)) seats: number; ->seats : Symbol(Car.seats, Decl(mappedTypeAsClauses.ts, 62, 17)) +>seats : Symbol(Car.seats, Decl(mappedTypeAsClauses.ts, 63, 17)) engine: Engine; ->engine : Symbol(Car.engine, Decl(mappedTypeAsClauses.ts, 63, 18)) ->Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 66, 1)) +>engine : Symbol(Car.engine, Decl(mappedTypeAsClauses.ts, 64, 18)) +>Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 67, 1)) wheels: Wheel[]; ->wheels : Symbol(Car.wheels, Decl(mappedTypeAsClauses.ts, 64, 19)) ->Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 71, 1)) +>wheels : Symbol(Car.wheels, Decl(mappedTypeAsClauses.ts, 65, 19)) +>Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 72, 1)) } interface Engine { ->Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 66, 1)) +>Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 67, 1)) manufacturer: string; ->manufacturer : Symbol(Engine.manufacturer, Decl(mappedTypeAsClauses.ts, 68, 18)) +>manufacturer : Symbol(Engine.manufacturer, Decl(mappedTypeAsClauses.ts, 69, 18)) horsepower: number; ->horsepower : Symbol(Engine.horsepower, Decl(mappedTypeAsClauses.ts, 69, 25)) +>horsepower : Symbol(Engine.horsepower, Decl(mappedTypeAsClauses.ts, 70, 25)) } interface Wheel { ->Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 71, 1)) +>Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 72, 1)) type: "summer" | "winter"; ->type : Symbol(Wheel.type, Decl(mappedTypeAsClauses.ts, 73, 17)) +>type : Symbol(Wheel.type, Decl(mappedTypeAsClauses.ts, 74, 17)) radius: number; ->radius : Symbol(Wheel.radius, Decl(mappedTypeAsClauses.ts, 74, 30)) +>radius : Symbol(Wheel.radius, Decl(mappedTypeAsClauses.ts, 75, 30)) } type Primitive = string | number | boolean; ->Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 76, 1)) +>Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 77, 1)) type OnlyPrimitives = { [K in keyof T as T[K] extends Primitive ? K : never]: T[K] }; ->OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28)) ->Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 76, 1)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28)) +>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 79, 43)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 80, 20)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 80, 28)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 80, 20)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 80, 20)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 80, 28)) +>Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 77, 1)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 80, 28)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 80, 20)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 80, 28)) let primitiveCar: OnlyPrimitives; // { name: string; seats: number; } ->primitiveCar : Symbol(primitiveCar, Decl(mappedTypeAsClauses.ts, 81, 3)) ->OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43)) ->Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21)) +>primitiveCar : Symbol(primitiveCar, Decl(mappedTypeAsClauses.ts, 82, 3)) +>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 79, 43)) +>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 58, 21)) let keys: keyof OnlyPrimitives; // "name" | "seats" ->keys : Symbol(keys, Decl(mappedTypeAsClauses.ts, 82, 3)) ->OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43)) ->Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21)) +>keys : Symbol(keys, Decl(mappedTypeAsClauses.ts, 83, 3)) +>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 79, 43)) +>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 58, 21)) type KeysOfPrimitives = keyof OnlyPrimitives; ->KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 82, 36)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 84, 22)) ->OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 84, 22)) +>KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 83, 36)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 85, 22)) +>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 79, 43)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 85, 22)) let carKeys: KeysOfPrimitives; // "name" | "seats" ->carKeys : Symbol(carKeys, Decl(mappedTypeAsClauses.ts, 86, 3)) ->KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 82, 36)) ->Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21)) +>carKeys : Symbol(carKeys, Decl(mappedTypeAsClauses.ts, 87, 3)) +>KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 83, 36)) +>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 58, 21)) // Repro from #41453 type Equal = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false; ->Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35)) ->A : Symbol(A, Decl(mappedTypeAsClauses.ts, 90, 11)) ->B : Symbol(B, Decl(mappedTypeAsClauses.ts, 90, 13)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 21)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 21)) ->A : Symbol(A, Decl(mappedTypeAsClauses.ts, 90, 11)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 60)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 60)) ->B : Symbol(B, Decl(mappedTypeAsClauses.ts, 90, 13)) +>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 87, 35)) +>A : Symbol(A, Decl(mappedTypeAsClauses.ts, 91, 11)) +>B : Symbol(B, Decl(mappedTypeAsClauses.ts, 91, 13)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 91, 21)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 91, 21)) +>A : Symbol(A, Decl(mappedTypeAsClauses.ts, 91, 11)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 91, 60)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 91, 60)) +>B : Symbol(B, Decl(mappedTypeAsClauses.ts, 91, 13)) type If = Cond extends true ? Then : Else; ->If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104)) ->Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 92, 8)) ->Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 92, 29)) ->Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 92, 35)) ->Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 92, 8)) ->Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 92, 29)) ->Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 92, 35)) +>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 91, 104)) +>Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 93, 8)) +>Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 93, 29)) +>Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 93, 35)) +>Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 93, 8)) +>Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 93, 29)) +>Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 93, 35)) type GetKey = keyof { [TP in keyof S as Equal extends true ? TP : never]: any }; ->GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 92, 76)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 94, 14)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12)) ->Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 94, 14)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29)) +>GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 93, 76)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 95, 12)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 95, 14)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 95, 29)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 95, 12)) +>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 87, 35)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 95, 12)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 95, 29)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 95, 14)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 95, 29)) type GetKeyWithIf = keyof { [TP in keyof S as If, TP, never>]: any }; ->GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 94, 96)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 96, 20)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18)) ->If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104)) ->Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 96, 20)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35)) +>GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 95, 96)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 97, 18)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 97, 20)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 97, 35)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 97, 18)) +>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 91, 104)) +>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 87, 35)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 97, 18)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 97, 35)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 97, 20)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 97, 35)) type GetObjWithIf = { [TP in keyof S as If, TP, never>]: any }; ->GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 96, 91)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 98, 20)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18)) ->If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104)) ->Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35)) ->S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 98, 20)) ->TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29)) +>GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 97, 91)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 99, 18)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 99, 20)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 99, 29)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 99, 18)) +>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 91, 104)) +>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 87, 35)) +>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 99, 18)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 99, 29)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 99, 20)) +>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 99, 29)) type Task = { ->Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85)) +>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 99, 85)) isDone: boolean; ->isDone : Symbol(isDone, Decl(mappedTypeAsClauses.ts, 100, 13)) +>isDone : Symbol(isDone, Decl(mappedTypeAsClauses.ts, 101, 13)) }; type Schema = { ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) root: { ->root : Symbol(root, Decl(mappedTypeAsClauses.ts, 104, 15)) +>root : Symbol(root, Decl(mappedTypeAsClauses.ts, 105, 15)) title: string; ->title : Symbol(title, Decl(mappedTypeAsClauses.ts, 105, 9)) +>title : Symbol(title, Decl(mappedTypeAsClauses.ts, 106, 9)) task: Task; ->task : Symbol(task, Decl(mappedTypeAsClauses.ts, 106, 18)) ->Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85)) +>task : Symbol(task, Decl(mappedTypeAsClauses.ts, 107, 18)) +>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 99, 85)) } Task: Task; ->Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 108, 3)) ->Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85)) +>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 109, 3)) +>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 99, 85)) }; type Res1 = GetKey; // "Task" ->Res1 : Symbol(Res1, Decl(mappedTypeAsClauses.ts, 110, 2)) ->GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 92, 76)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) +>Res1 : Symbol(Res1, Decl(mappedTypeAsClauses.ts, 111, 2)) +>GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 93, 76)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) type Res2 = GetKeyWithIf; // "Task" ->Res2 : Symbol(Res2, Decl(mappedTypeAsClauses.ts, 112, 51)) ->GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 94, 96)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) +>Res2 : Symbol(Res2, Decl(mappedTypeAsClauses.ts, 113, 51)) +>GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 95, 96)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) type Res3 = keyof GetObjWithIf; // "Task" ->Res3 : Symbol(Res3, Decl(mappedTypeAsClauses.ts, 113, 57)) ->GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 96, 91)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) ->Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2)) +>Res3 : Symbol(Res3, Decl(mappedTypeAsClauses.ts, 114, 57)) +>GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 97, 91)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) +>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 103, 2)) // Repro from #44019 type KeysExtendedBy = keyof { [K in keyof T as U extends T[K] ? K : never] : T[K] }; ->KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 114, 63)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 118, 22)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 118, 22)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37)) +>KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 115, 63)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 119, 20)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 119, 22)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 119, 37)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 119, 20)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 119, 22)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 119, 20)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 119, 37)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 119, 37)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 119, 20)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 119, 37)) interface M { ->M : Symbol(M, Decl(mappedTypeAsClauses.ts, 118, 90)) +>M : Symbol(M, Decl(mappedTypeAsClauses.ts, 119, 90)) a: boolean; ->a : Symbol(M.a, Decl(mappedTypeAsClauses.ts, 120, 13)) +>a : Symbol(M.a, Decl(mappedTypeAsClauses.ts, 121, 13)) b: number; ->b : Symbol(M.b, Decl(mappedTypeAsClauses.ts, 121, 15)) +>b : Symbol(M.b, Decl(mappedTypeAsClauses.ts, 122, 15)) } function f(x: KeysExtendedBy) { ->f : Symbol(f, Decl(mappedTypeAsClauses.ts, 123, 1)) ->x : Symbol(x, Decl(mappedTypeAsClauses.ts, 125, 11)) ->KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 114, 63)) ->M : Symbol(M, Decl(mappedTypeAsClauses.ts, 118, 90)) +>f : Symbol(f, Decl(mappedTypeAsClauses.ts, 124, 1)) +>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 126, 11)) +>KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 115, 63)) +>M : Symbol(M, Decl(mappedTypeAsClauses.ts, 119, 90)) return x; ->x : Symbol(x, Decl(mappedTypeAsClauses.ts, 125, 11)) +>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 126, 11)) } f("a"); // Error, should allow only "b" ->f : Symbol(f, Decl(mappedTypeAsClauses.ts, 123, 1)) +>f : Symbol(f, Decl(mappedTypeAsClauses.ts, 124, 1)) type NameMap = { 'a': 'x', 'b': 'y', 'c': 'z' }; ->NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7)) ->'a' : Symbol('a', Decl(mappedTypeAsClauses.ts, 131, 16)) ->'b' : Symbol('b', Decl(mappedTypeAsClauses.ts, 131, 26)) ->'c' : Symbol('c', Decl(mappedTypeAsClauses.ts, 131, 36)) +>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 130, 7)) +>'a' : Symbol('a', Decl(mappedTypeAsClauses.ts, 132, 16)) +>'b' : Symbol('b', Decl(mappedTypeAsClauses.ts, 132, 26)) +>'c' : Symbol('c', Decl(mappedTypeAsClauses.ts, 132, 36)) // Distributive, will be simplified type TS0 = keyof { [P in keyof T as keyof Record]: string }; ->TS0 : Symbol(TS0, Decl(mappedTypeAsClauses.ts, 131, 48)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 135, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 135, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 135, 9)) +>TS0 : Symbol(TS0, Decl(mappedTypeAsClauses.ts, 132, 48)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 135, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23)) type TS1 = keyof { [P in keyof T as Extract]: string }; ->TS1 : Symbol(TS1, Decl(mappedTypeAsClauses.ts, 135, 74)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9)) +>TS1 : Symbol(TS1, Decl(mappedTypeAsClauses.ts, 136, 74)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9)) >Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23)) type TS2 = keyof { [P in keyof T as P & ('a' | 'b' | 'c')]: string }; ->TS2 : Symbol(TS2, Decl(mappedTypeAsClauses.ts, 136, 78)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23)) +>TS2 : Symbol(TS2, Decl(mappedTypeAsClauses.ts, 137, 78)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23)) type TS3 = keyof { [P in keyof T as Exclude]: string }; ->TS3 : Symbol(TS3, Decl(mappedTypeAsClauses.ts, 137, 72)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9)) +>TS3 : Symbol(TS3, Decl(mappedTypeAsClauses.ts, 138, 72)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9)) >Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23)) type TS4 = keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string }; ->TS4 : Symbol(TS4, Decl(mappedTypeAsClauses.ts, 138, 78)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9)) ->NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23)) ->NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7)) +>TS4 : Symbol(TS4, Decl(mappedTypeAsClauses.ts, 139, 78)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9)) +>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 130, 7)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23)) +>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 130, 7)) type TS5 = keyof { [P in keyof T & keyof NameMap as NameMap[P]]: string }; ->TS5 : Symbol(TS5, Decl(mappedTypeAsClauses.ts, 139, 77)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9)) ->NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7)) ->NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23)) +>TS5 : Symbol(TS5, Decl(mappedTypeAsClauses.ts, 140, 77)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 141, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9)) +>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 130, 7)) +>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 130, 7)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 141, 23)) type TS6 = keyof { [ K in keyof T as V & (K extends U ? K : never)]: string }; ->TS6 : Symbol(TS6, Decl(mappedTypeAsClauses.ts, 140, 77)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 141, 11)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 141, 14)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9)) ->V : Symbol(V, Decl(mappedTypeAsClauses.ts, 141, 14)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 141, 11)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29)) +>TS6 : Symbol(TS6, Decl(mappedTypeAsClauses.ts, 141, 77)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 142, 9)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 142, 11)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 142, 14)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 142, 29)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 142, 9)) +>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 142, 14)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 142, 29)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 142, 11)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 142, 29)) // Non-distributive, won't be simplified type TN0 = keyof { [P in keyof T as T[P] extends number ? P : never]: string }; ->TN0 : Symbol(TN0, Decl(mappedTypeAsClauses.ts, 141, 87)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23)) +>TN0 : Symbol(TN0, Decl(mappedTypeAsClauses.ts, 142, 87)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) type TN1 = keyof { [P in keyof T as number extends T[P] ? P : never]: string }; ->TN1 : Symbol(TN1, Decl(mappedTypeAsClauses.ts, 145, 82)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23)) +>TN1 : Symbol(TN1, Decl(mappedTypeAsClauses.ts, 146, 82)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23)) type TN2 = keyof { [P in keyof T as 'a' extends P ? 'x' : 'y']: string }; ->TN2 : Symbol(TN2, Decl(mappedTypeAsClauses.ts, 146, 82)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23)) +>TN2 : Symbol(TN2, Decl(mappedTypeAsClauses.ts, 147, 82)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23)) type TN3 = keyof { [P in keyof T as Exclude, 'b'>, 'a'>]: string }; ->TN3 : Symbol(TN3, Decl(mappedTypeAsClauses.ts, 147, 76)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9)) +>TN3 : Symbol(TN3, Decl(mappedTypeAsClauses.ts, 148, 76)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 149, 23)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) >Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) >Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) >Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 149, 23)) type TN4 = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string }; ->TN4 : Symbol(TN4, Decl(mappedTypeAsClauses.ts, 148, 94)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 149, 11)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 149, 11)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26)) +>TN4 : Symbol(TN4, Decl(mappedTypeAsClauses.ts, 149, 94)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string }; ->TN5 : Symbol(TN5, Decl(mappedTypeAsClauses.ts, 149, 107)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 150, 51)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) ->T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9)) ->P : Symbol(P, Decl(mappedTypeAsClauses.ts, 150, 51)) ->U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11)) ->K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26)) +>TN5 : Symbol(TN5, Decl(mappedTypeAsClauses.ts, 150, 107)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 151, 9)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 151, 11)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 151, 26)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 151, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 151, 51)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 151, 26)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 151, 9)) +>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 151, 51)) +>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 151, 11)) +>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 151, 26)) + +// repro from https://github.com/microsoft/TypeScript/issues/55129 +type Fruit = +>Fruit : Symbol(Fruit, Decl(mappedTypeAsClauses.ts, 151, 108)) + + | { + name: "apple"; +>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 155, 5)) + + color: "red"; +>color : Symbol(color, Decl(mappedTypeAsClauses.ts, 156, 20)) + } + | { + name: "banana"; +>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 159, 5)) + + color: "yellow"; +>color : Symbol(color, Decl(mappedTypeAsClauses.ts, 160, 21)) + } + | { + name: "orange"; +>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 163, 5)) + + color: "orange"; +>color : Symbol(color, Decl(mappedTypeAsClauses.ts, 164, 21)) + + }; +type Result1 = { +>Result1 : Symbol(Result1, Decl(mappedTypeAsClauses.ts, 166, 6)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 167, 13)) +>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 167, 24)) +>color : Symbol(color, Decl(mappedTypeAsClauses.ts, 167, 46)) + + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 168, 3)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 167, 13)) +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 168, 3)) +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 168, 3)) + +}; +type Result2 = keyof { +>Result2 : Symbol(Result2, Decl(mappedTypeAsClauses.ts, 169, 2)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 170, 13)) +>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 170, 24)) +>color : Symbol(color, Decl(mappedTypeAsClauses.ts, 170, 46)) + + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 171, 3)) +>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 170, 13)) +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 171, 3)) +>Key : Symbol(Key, Decl(mappedTypeAsClauses.ts, 171, 3)) +} +type Test1 = keyof Result1 // "apple:red" | "banana:yellow" | "orange:orange" +>Test1 : Symbol(Test1, Decl(mappedTypeAsClauses.ts, 172, 1)) +>Result1 : Symbol(Result1, Decl(mappedTypeAsClauses.ts, 166, 6)) +>Fruit : Symbol(Fruit, Decl(mappedTypeAsClauses.ts, 151, 108)) + +type Test2 = Result2 // "apple:red" | "banana:yellow" | "orange:orange" +>Test2 : Symbol(Test2, Decl(mappedTypeAsClauses.ts, 173, 33)) +>Result2 : Symbol(Result2, Decl(mappedTypeAsClauses.ts, 169, 2)) +>Fruit : Symbol(Fruit, Decl(mappedTypeAsClauses.ts, 151, 108)) diff --git a/tests/baselines/reference/mappedTypeAsClauses.types b/tests/baselines/reference/mappedTypeAsClauses.types index f9d426c0e8f..168e8bd6eaf 100644 --- a/tests/baselines/reference/mappedTypeAsClauses.types +++ b/tests/baselines/reference/mappedTypeAsClauses.types @@ -65,8 +65,13 @@ type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' >TD2 : "a1" | "b1" | "a2" | "b2" -type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` ->TD3 : `${keyof U & string}1` | `${keyof U & string}2` +type TD3 = keyof DoubleProp; // keyof DoubleProp +>TD3 : keyof DoubleProp + +type TD4 = TD3<{ a: string, b: number }>; // 'a1' | 'a2' | 'b1' | 'b2' +>TD4 : "a1" | "b1" | "a2" | "b2" +>a : string +>b : number // Repro from #40619 @@ -277,7 +282,7 @@ type TS4 = keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string }; >TS4 : keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string; } type TS5 = keyof { [P in keyof T & keyof NameMap as NameMap[P]]: string }; ->TS5 : NameMap[keyof T & "a"] | NameMap[keyof T & "b"] | NameMap[keyof T & "c"] +>TS5 : keyof { [P in keyof T & keyof NameMap as NameMap[P]]: string; } type TS6 = keyof { [ K in keyof T as V & (K extends U ? K : never)]: string }; >TS6 : keyof { [K in keyof T as V & (K extends U ? K : never)]: string; } @@ -303,3 +308,49 @@ type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K >TN5 : keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true; }]: string; } >true : true +// repro from https://github.com/microsoft/TypeScript/issues/55129 +type Fruit = +>Fruit : { name: "apple"; color: "red"; } | { name: "banana"; color: "yellow"; } | { name: "orange"; color: "orange"; } + + | { + name: "apple"; +>name : "apple" + + color: "red"; +>color : "red" + } + | { + name: "banana"; +>name : "banana" + + color: "yellow"; +>color : "yellow" + } + | { + name: "orange"; +>name : "orange" + + color: "orange"; +>color : "orange" + + }; +type Result1 = { +>Result1 : Result1 +>name : string | number +>color : string | number + + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +}; +type Result2 = keyof { +>Result2 : keyof { [Key in T as `${Key["name"]}:${Key["color"]}`]: unknown; } +>name : string | number +>color : string | number + + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +} +type Test1 = keyof Result1 // "apple:red" | "banana:yellow" | "orange:orange" +>Test1 : "apple:red" | "banana:yellow" | "orange:orange" + +type Test2 = Result2 // "apple:red" | "banana:yellow" | "orange:orange" +>Test2 : "apple:red" | "banana:yellow" | "orange:orange" + diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt new file mode 100644 index 00000000000..ec7eab991b0 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt @@ -0,0 +1,225 @@ +reverseMappedTypeIntersectionConstraint.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeIntersectionConstraint.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeIntersectionConstraint.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeIntersectionConstraint.ts(59,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeIntersectionConstraint.ts(63,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(69,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. + Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeIntersectionConstraint.ts(74,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(87,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(98,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(100,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeIntersectionConstraint.ts(113,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeIntersectionConstraint.ts(152,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +reverseMappedTypeIntersectionConstraint.ts(164,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. + + +==== reverseMappedTypeIntersectionConstraint.ts (14 errors) ==== + type StateConfig = { + entry?: TAction + states?: Record>; + }; + + type StateSchema = { + states?: Record; + }; + + declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, + >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + + const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + ~~~~~ +!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. +!!! related TS6500 reverseMappedTypeIntersectionConstraint.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' + }, + }, + extra: 12, + }); + + const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. + }); + + + // ----------------------------------------------------------------------------------------- + + const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); + + checked; + + // ----------------------------------------------------------------------------------------- + + interface Stuff { + field: number; + anotherField: string; + } + + function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + + function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + ]) + + // ----------------------------------------------------------------------------------------- + + type XNumber = { x: number } + + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + + function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design + } + + foo({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + + // ----------------------------------------------------------------------------------------- + + type NoErrWithOptProps = { x: number, y?: string } + + declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + + baz({x: 1}); + baz({x: 1, z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. + baz({x: 1, y: 'foo'}); + baz({x: 1, y: 'foo', z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. + + // ----------------------------------------------------------------------------------------- + + interface WithNestedProp { + prop: string; + nested: { + prop: string; + } + } + + declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + + const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. + + // ----------------------------------------------------------------------------------------- + + type IsLiteralString = string extends T ? false : true; + + type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + + interface ProvidedActor { + src: string; + logic: () => Promise; + } + + type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + + interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; + } + + type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never + } + + declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, + >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + + const child = () => Promise.resolve("foo"); + ~~~~~~~ +!!! error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + + const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. + }); + + const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. + }); + \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js new file mode 100644 index 00000000000..a68576c793b --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js @@ -0,0 +1,260 @@ +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// + +//// [reverseMappedTypeIntersectionConstraint.ts] +type StateConfig = { + entry?: TAction + states?: Record>; +}; + +type StateSchema = { + states?: Record; +}; + +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +checked; + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +foo({x: 1, y: 'foo'}); + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +}); + +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 +}); + + +//// [reverseMappedTypeIntersectionConstraint.js] +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); +var inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); +// ----------------------------------------------------------------------------------------- +var checkType = function () { return function (value) { return value; }; }; +var checked = checkType()({ + x: 1, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); +checked; +function doStuffWithStuff(s) { + if (Math.random() > 0.5) { + return s; + } + else { + return s; + } +} +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); +function doStuffWithStuffArr(arr) { + if (Math.random() > 0.5) { + return arr; + } + else { + return arr; + } +} +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]); +function bar(props) { + return foo(props); // no error because lack of excess property check by design +} +foo({ x: 1, y: 'foo' }); +foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design +baz({ x: 1 }); +baz({ x: 1, z: 123 }); +baz({ x: 1, y: 'foo' }); +baz({ x: 1, y: 'foo', z: 123 }); +var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +var child = function () { return Promise.resolve("foo"); }; +var config = createXMachine({ + types: {}, + invoke: { + src: "str", + }, + extra: 10 +}); +var config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 +}); diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols new file mode 100644 index 00000000000..12cb8664c84 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols @@ -0,0 +1,491 @@ +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// + +=== reverseMappedTypeIntersectionConstraint.ts === +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + entry?: TAction +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 1, 17)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + +}; + +type StateSchema = { +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + + states?: Record; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + +}; + +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) + + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 15, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 17, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 4)) + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 25, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 27, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 30, 4)) + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) + +const checked = checkType<{x: number, y: string}>()({ +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 27)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 37)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 53)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 40, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 41, 9)) + +}); + +checked; +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) + +// ----------------------------------------------------------------------------------------- + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) + + field: number; +>field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 49, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 18)) +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) + + } else { + return s +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 18)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 28)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 47)) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[] +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) + + } else { + return arr +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) + + { field: 1, anotherField: 'a', extra: 123 }, +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 34)) + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 40)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) + +function bar(props: {x: number, y: string}) { +>bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 93)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 21)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 31)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +} + +foo({x: 1, y: 'foo'}); +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 10)) + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 9)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 14)) + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 26)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 37)) + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 50)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) + +baz({x: 1}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 96, 5)) + +baz({x: 1, z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 10)) + +baz({x: 1, y: 'foo'}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) + +baz({x: 1, y: 'foo', z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 20)) + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) + + prop: string; +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 103, 26)) + + nested: { +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 15)) + + prop: string; +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 11)) + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 58)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 65)) + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) + +interface ProvidedActor { +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + + src: string; +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 25)) + + logic: () => Promise; +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) + + ? { + src: TSrc; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) + } + : never; + +interface MachineConfig { +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + + types?: { +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 55)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + }; + invoke: IsLiteralString extends true +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + ? DistributeActors +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + : { + src: string; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 7)) + + }; +} + +type NoExtra = { +>NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +} + +declare function createXMachine< +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + const TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) + + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) + +const child = () => Promise.resolve("foo"); +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) + +const config = createXMachine({ +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + types: {} as { +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 31)) + + actors: { +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 16)) + + src: "str"; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 13)) + + logic: typeof child; +>logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 17)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) + + }; + }, + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 4)) + + src: "str", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 160, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 162, 4)) + +}); + +const config2 = createXMachine({ +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 32)) + + src: "whatever", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 167, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 4)) + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types new file mode 100644 index 00000000000..43b568dd83d --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types @@ -0,0 +1,461 @@ +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// + +=== reverseMappedTypeIntersectionConstraint.ts === +type StateConfig = { +>StateConfig : StateConfig + + entry?: TAction +>entry : TAction | undefined + + states?: Record>; +>states : Record> | undefined + +}; + +type StateSchema = { +>StateSchema : { states?: Record | undefined; } + + states?: Record; +>states : Record | undefined + +}; + +declare function createMachine< +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] + + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } + +const inferredParams1 = createMachine({ +>inferredParams1 : ["foo", StateConfig<"foo">] +>createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "bar"; }; } +>{ a: { entry: "bar", }, } : { a: { entry: "bar"; }; } + + a: { +>a : { entry: "bar"; } +>{ entry: "bar", } : { entry: "bar"; } + + entry: "bar", +>entry : "bar" +>"bar" : "bar" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "foo"; }; } +>{ a: { entry: "foo", }, } : { a: { entry: "foo"; }; } + + a: { +>a : { entry: "foo"; } +>{ entry: "foo", } : { entry: "foo"; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked = checkType<{x: number, y: string}>()({ +>checked : { x: number; y: "y"; } +>checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed}) : { x: number; y: "y"; } +>checkType<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", // undesirable property z is *not* allowed +>z : string +>"z" : "z" + +}); + +checked; +>checked : { x: number; y: "y"; } + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; +>field : number + + anotherField: string; +>anotherField : string +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return s as T +>s as T : T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + } else { + return s +>s : { [K in keyof T & keyof Stuff]: T[K]; } + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return arr as T[] +>arr as T[] : T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + } else { + return arr +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] + + { field: 1, anotherField: 'a', extra: 123 }, +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : { x: number; } +>x : number + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>props : { [K in keyof T & "x"]: T[K]; } + +function bar(props: {x: number, y: string}) { +>bar : (props: { x: number; y: string;}) => void +>props : { x: number; y: string; } +>x : number +>y : string + + return foo(props); // no error because lack of excess property check by design +>foo(props) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>props : { x: number; y: string; } +} + +foo({x: 1, y: 'foo'}); +>foo({x: 1, y: 'foo'}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo({...{x: 1, y: 'foo'}}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>{...{x: 1, y: 'foo'}} : { x: 1; y: string; } +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : { x: number; y?: string | undefined; } +>x : number +>y : string | undefined + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } + +baz({x: 1}); +>baz({x: 1}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1} : { x: 1; } +>x : 1 +>1 : 1 + +baz({x: 1, z: 123}); +>baz({x: 1, z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, z: 123} : { x: 1; z: number; } +>x : 1 +>1 : 1 +>z : number +>123 : 123 + +baz({x: 1, y: 'foo'}); +>baz({x: 1, y: 'foo'}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, y: 'foo'} : { x: 1; y: "foo"; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" + +baz({x: 1, y: 'foo', z: 123}); +>baz({x: 1, y: 'foo', z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" +>z : number +>123 : 123 + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; +>prop : string + + nested: { +>nested : { prop: string; } + + prop: string; +>prop : string + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>props : { [K in keyof T & keyof WithNestedProp]: T[K]; } + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>{prop: 'foo', nested: { prop: 'bar' }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } +>prop : "foo" +>'foo' : "foo" +>nested : { prop: string; } +>{ prop: 'bar' } : { prop: string; } +>prop : string +>'bar' : "bar" +>extra : number +>10 : 10 + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : IsLiteralString +>false : false +>true : true + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : DeepWritable + +interface ProvidedActor { + src: string; +>src : string + + logic: () => Promise; +>logic : () => Promise +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : DistributeActors +>src : TSrc + + ? { + src: TSrc; +>src : TSrc + } + : never; + +interface MachineConfig { + types?: { +>types : { actors?: TActor | undefined; } | undefined + + actors?: TActor; +>actors : TActor | undefined + + }; + invoke: IsLiteralString extends true +>invoke : IsLiteralString extends true ? DistributeActors : { src: string; } +>true : true + + ? DistributeActors + : { + src: string; +>src : string + + }; +} + +type NoExtra = { +>NoExtra : NoExtra + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createXMachine< +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig + + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>types : { actors: ProvidedActor; } +>actors : ProvidedActor + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } + +const child = () => Promise.resolve("foo"); +>child : () => any +>() => Promise.resolve("foo") : () => any +>Promise.resolve("foo") : any +>Promise.resolve : any +>Promise : any +>resolve : any +>"foo" : "foo" + +const config = createXMachine({ +>config : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } + + types: {} as { +>types : { actors: { src: "str"; logic: typeof child;}; } +>{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } +>{} : {} + + actors: { +>actors : { src: "str"; logic: typeof child; } + + src: "str"; +>src : "str" + + logic: typeof child; +>logic : () => any +>child : () => any + + }; + }, + invoke: { +>invoke : { src: "str"; } +>{ src: "str", } : { src: "str"; } + + src: "str", +>src : "str" +>"str" : "str" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + +const config2 = createXMachine({ +>config2 : { invoke: { readonly src: "whatever"; }; } +>createXMachine({ invoke: { src: "whatever", }, extra: 10}) : { invoke: { readonly src: "whatever"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ invoke: { src: "whatever", }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } + + invoke: { +>invoke : { src: "whatever"; } +>{ src: "whatever", } : { src: "whatever"; } + + src: "whatever", +>src : "whatever" +>"whatever" : "whatever" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt new file mode 100644 index 00000000000..dc6dc8fa3a3 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt @@ -0,0 +1,24 @@ +reverseMappedTypeLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + + +==== reverseMappedTypeLimitedConstraint.ts (2 errors) ==== + type XNumber_ = { x: number } + + declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + + foo_({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + // ----------------------------------------------------------------------------------------- + + const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js new file mode 100644 index 00000000000..0be7aa8d6a4 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +//// [reverseMappedTypeLimitedConstraint.ts] +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); + +//// [reverseMappedTypeLimitedConstraint.js] +foo_({ x: 1, y: 'foo' }); +// ----------------------------------------------------------------------------------------- +var checkType_ = function () { return function (value) { return value; }; }; +var checked_ = checkType_()({ + x: 1, + y: "y", + z: "z", +}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols new file mode 100644 index 00000000000..5c815072784 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +=== reverseMappedTypeLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 17)) + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) + +foo_({x: 1, y: 'foo'}); +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 6)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 11)) + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 5)) +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 29)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 11, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraint.ts, 12, 9)) + +}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types new file mode 100644 index 00000000000..821d7685fcc --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +=== reverseMappedTypeLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : { x: number; } +>x : number + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>props : { [K in keyof T & "x"]: T[K]; } + +foo_({x: 1, y: 'foo'}); +>foo_({x: 1, y: 'foo'}) : { x: 1; } +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z",}) : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z",} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", +>z : string +>"z" : "z" + +}); diff --git a/tests/baselines/reference/reverseMappedUnionInference.symbols b/tests/baselines/reference/reverseMappedUnionInference.symbols new file mode 100644 index 00000000000..ec09965565d --- /dev/null +++ b/tests/baselines/reference/reverseMappedUnionInference.symbols @@ -0,0 +1,172 @@ +//// [tests/cases/compiler/reverseMappedUnionInference.ts] //// + +=== reverseMappedUnionInference.ts === +interface AnyExtractor { +>AnyExtractor : Symbol(AnyExtractor, Decl(reverseMappedUnionInference.ts, 0, 0)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 0, 23)) + + matches: (node: any) => boolean; +>matches : Symbol(AnyExtractor.matches, Decl(reverseMappedUnionInference.ts, 0, 32)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 1, 12)) + + extract: (node: any) => Result | undefined; +>extract : Symbol(AnyExtractor.extract, Decl(reverseMappedUnionInference.ts, 1, 34)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 2, 12)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 0, 23)) +} + +interface Extractor { +>Extractor : Symbol(Extractor, Decl(reverseMappedUnionInference.ts, 3, 1)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 5, 20)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 5, 22)) + + matches: (node: unknown) => node is T; +>matches : Symbol(Extractor.matches, Decl(reverseMappedUnionInference.ts, 5, 32)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 6, 12)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 6, 12)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 5, 20)) + + extract: (node: T) => Result | undefined; +>extract : Symbol(Extractor.extract, Decl(reverseMappedUnionInference.ts, 6, 40)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 7, 12)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 5, 20)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 5, 22)) +} + +declare function createExtractor(params: { +>createExtractor : Symbol(createExtractor, Decl(reverseMappedUnionInference.ts, 8, 1)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 10, 33)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 10, 35)) +>params : Symbol(params, Decl(reverseMappedUnionInference.ts, 10, 44)) + + matcher: (node: unknown) => node is T; +>matcher : Symbol(matcher, Decl(reverseMappedUnionInference.ts, 10, 53)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 11, 12)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 11, 12)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 10, 33)) + + extract: (node: T) => Result; +>extract : Symbol(extract, Decl(reverseMappedUnionInference.ts, 11, 40)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 12, 12)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 10, 33)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 10, 35)) + +}): Extractor; +>Extractor : Symbol(Extractor, Decl(reverseMappedUnionInference.ts, 3, 1)) +>T : Symbol(T, Decl(reverseMappedUnionInference.ts, 10, 33)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 10, 35)) + +interface Identifier { +>Identifier : Symbol(Identifier, Decl(reverseMappedUnionInference.ts, 13, 25)) + + kind: "identifier"; +>kind : Symbol(Identifier.kind, Decl(reverseMappedUnionInference.ts, 15, 22)) + + name: string; +>name : Symbol(Identifier.name, Decl(reverseMappedUnionInference.ts, 16, 21)) +} + +declare function isIdentifier(node: unknown): node is Identifier; +>isIdentifier : Symbol(isIdentifier, Decl(reverseMappedUnionInference.ts, 18, 1)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 20, 30)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 20, 30)) +>Identifier : Symbol(Identifier, Decl(reverseMappedUnionInference.ts, 13, 25)) + +const identifierExtractor = createExtractor({ +>identifierExtractor : Symbol(identifierExtractor, Decl(reverseMappedUnionInference.ts, 22, 5)) +>createExtractor : Symbol(createExtractor, Decl(reverseMappedUnionInference.ts, 8, 1)) + + matcher: isIdentifier, +>matcher : Symbol(matcher, Decl(reverseMappedUnionInference.ts, 22, 45)) +>isIdentifier : Symbol(isIdentifier, Decl(reverseMappedUnionInference.ts, 18, 1)) + + extract: (node) => { +>extract : Symbol(extract, Decl(reverseMappedUnionInference.ts, 23, 24)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 24, 12)) + + return { + node, +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 25, 12)) + + kind: "identifier" as const, +>kind : Symbol(kind, Decl(reverseMappedUnionInference.ts, 26, 11)) +>const : Symbol(const) + + value: node.name, +>value : Symbol(value, Decl(reverseMappedUnionInference.ts, 27, 34)) +>node.name : Symbol(Identifier.name, Decl(reverseMappedUnionInference.ts, 16, 21)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 24, 12)) +>name : Symbol(Identifier.name, Decl(reverseMappedUnionInference.ts, 16, 21)) + + }; + }, +}); + +interface StringLiteral { +>StringLiteral : Symbol(StringLiteral, Decl(reverseMappedUnionInference.ts, 31, 3)) + + kind: "stringLiteral"; +>kind : Symbol(StringLiteral.kind, Decl(reverseMappedUnionInference.ts, 33, 25)) + + value: string; +>value : Symbol(StringLiteral.value, Decl(reverseMappedUnionInference.ts, 34, 24)) +} + +declare function isStringLiteral(node: unknown): node is StringLiteral; +>isStringLiteral : Symbol(isStringLiteral, Decl(reverseMappedUnionInference.ts, 36, 1)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 38, 33)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 38, 33)) +>StringLiteral : Symbol(StringLiteral, Decl(reverseMappedUnionInference.ts, 31, 3)) + +const stringExtractor = createExtractor({ +>stringExtractor : Symbol(stringExtractor, Decl(reverseMappedUnionInference.ts, 40, 5)) +>createExtractor : Symbol(createExtractor, Decl(reverseMappedUnionInference.ts, 8, 1)) + + matcher: isStringLiteral, +>matcher : Symbol(matcher, Decl(reverseMappedUnionInference.ts, 40, 41)) +>isStringLiteral : Symbol(isStringLiteral, Decl(reverseMappedUnionInference.ts, 36, 1)) + + extract: (node) => { +>extract : Symbol(extract, Decl(reverseMappedUnionInference.ts, 41, 27)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 42, 12)) + + return { + node, +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 43, 12)) + + kind: "string" as const, +>kind : Symbol(kind, Decl(reverseMappedUnionInference.ts, 44, 11)) +>const : Symbol(const) + + value: node.value, +>value : Symbol(value, Decl(reverseMappedUnionInference.ts, 45, 30)) +>node.value : Symbol(StringLiteral.value, Decl(reverseMappedUnionInference.ts, 34, 24)) +>node : Symbol(node, Decl(reverseMappedUnionInference.ts, 42, 12)) +>value : Symbol(StringLiteral.value, Decl(reverseMappedUnionInference.ts, 34, 24)) + + }; + }, +}); + +declare function unionType(parsers: { +>unionType : Symbol(unionType, Decl(reverseMappedUnionInference.ts, 49, 3)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 51, 27)) +>parsers : Symbol(parsers, Decl(reverseMappedUnionInference.ts, 51, 62)) + + [K in keyof Result]: AnyExtractor; +>K : Symbol(K, Decl(reverseMappedUnionInference.ts, 52, 3)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 51, 27)) +>AnyExtractor : Symbol(AnyExtractor, Decl(reverseMappedUnionInference.ts, 0, 0)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 51, 27)) +>K : Symbol(K, Decl(reverseMappedUnionInference.ts, 52, 3)) + +}): AnyExtractor; +>AnyExtractor : Symbol(AnyExtractor, Decl(reverseMappedUnionInference.ts, 0, 0)) +>Result : Symbol(Result, Decl(reverseMappedUnionInference.ts, 51, 27)) + +const myUnion = unionType([identifierExtractor, stringExtractor]); +>myUnion : Symbol(myUnion, Decl(reverseMappedUnionInference.ts, 55, 5)) +>unionType : Symbol(unionType, Decl(reverseMappedUnionInference.ts, 49, 3)) +>identifierExtractor : Symbol(identifierExtractor, Decl(reverseMappedUnionInference.ts, 22, 5)) +>stringExtractor : Symbol(stringExtractor, Decl(reverseMappedUnionInference.ts, 40, 5)) + diff --git a/tests/baselines/reference/reverseMappedUnionInference.types b/tests/baselines/reference/reverseMappedUnionInference.types new file mode 100644 index 00000000000..0ce2b95184f --- /dev/null +++ b/tests/baselines/reference/reverseMappedUnionInference.types @@ -0,0 +1,148 @@ +//// [tests/cases/compiler/reverseMappedUnionInference.ts] //// + +=== reverseMappedUnionInference.ts === +interface AnyExtractor { + matches: (node: any) => boolean; +>matches : (node: any) => boolean +>node : any + + extract: (node: any) => Result | undefined; +>extract : (node: any) => Result | undefined +>node : any +} + +interface Extractor { + matches: (node: unknown) => node is T; +>matches : (node: unknown) => node is T +>node : unknown + + extract: (node: T) => Result | undefined; +>extract : (node: T) => Result | undefined +>node : T +} + +declare function createExtractor(params: { +>createExtractor : (params: { matcher: (node: unknown) => node is T; extract: (node: T) => Result; }) => Extractor +>params : { matcher: (node: unknown) => node is T; extract: (node: T) => Result; } + + matcher: (node: unknown) => node is T; +>matcher : (node: unknown) => node is T +>node : unknown + + extract: (node: T) => Result; +>extract : (node: T) => Result +>node : T + +}): Extractor; + +interface Identifier { + kind: "identifier"; +>kind : "identifier" + + name: string; +>name : string +} + +declare function isIdentifier(node: unknown): node is Identifier; +>isIdentifier : (node: unknown) => node is Identifier +>node : unknown + +const identifierExtractor = createExtractor({ +>identifierExtractor : Extractor +>createExtractor({ matcher: isIdentifier, extract: (node) => { return { node, kind: "identifier" as const, value: node.name, }; },}) : Extractor +>createExtractor : (params: { matcher: (node: unknown) => node is T; extract: (node: T) => Result; }) => Extractor +>{ matcher: isIdentifier, extract: (node) => { return { node, kind: "identifier" as const, value: node.name, }; },} : { matcher: (node: unknown) => node is Identifier; extract: (node: Identifier) => { node: Identifier; kind: "identifier"; value: string; }; } + + matcher: isIdentifier, +>matcher : (node: unknown) => node is Identifier +>isIdentifier : (node: unknown) => node is Identifier + + extract: (node) => { +>extract : (node: Identifier) => { node: Identifier; kind: "identifier"; value: string; } +>(node) => { return { node, kind: "identifier" as const, value: node.name, }; } : (node: Identifier) => { node: Identifier; kind: "identifier"; value: string; } +>node : Identifier + + return { +>{ node, kind: "identifier" as const, value: node.name, } : { node: Identifier; kind: "identifier"; value: string; } + + node, +>node : Identifier + + kind: "identifier" as const, +>kind : "identifier" +>"identifier" as const : "identifier" +>"identifier" : "identifier" + + value: node.name, +>value : string +>node.name : string +>node : Identifier +>name : string + + }; + }, +}); + +interface StringLiteral { + kind: "stringLiteral"; +>kind : "stringLiteral" + + value: string; +>value : string +} + +declare function isStringLiteral(node: unknown): node is StringLiteral; +>isStringLiteral : (node: unknown) => node is StringLiteral +>node : unknown + +const stringExtractor = createExtractor({ +>stringExtractor : Extractor +>createExtractor({ matcher: isStringLiteral, extract: (node) => { return { node, kind: "string" as const, value: node.value, }; },}) : Extractor +>createExtractor : (params: { matcher: (node: unknown) => node is T; extract: (node: T) => Result; }) => Extractor +>{ matcher: isStringLiteral, extract: (node) => { return { node, kind: "string" as const, value: node.value, }; },} : { matcher: (node: unknown) => node is StringLiteral; extract: (node: StringLiteral) => { node: StringLiteral; kind: "string"; value: string; }; } + + matcher: isStringLiteral, +>matcher : (node: unknown) => node is StringLiteral +>isStringLiteral : (node: unknown) => node is StringLiteral + + extract: (node) => { +>extract : (node: StringLiteral) => { node: StringLiteral; kind: "string"; value: string; } +>(node) => { return { node, kind: "string" as const, value: node.value, }; } : (node: StringLiteral) => { node: StringLiteral; kind: "string"; value: string; } +>node : StringLiteral + + return { +>{ node, kind: "string" as const, value: node.value, } : { node: StringLiteral; kind: "string"; value: string; } + + node, +>node : StringLiteral + + kind: "string" as const, +>kind : "string" +>"string" as const : "string" +>"string" : "string" + + value: node.value, +>value : string +>node.value : string +>node : StringLiteral +>value : string + + }; + }, +}); + +declare function unionType(parsers: { +>unionType : (parsers: { [K in keyof Result]: AnyExtractor; }) => AnyExtractor +>parsers : { [K in keyof Result]: AnyExtractor; } + + [K in keyof Result]: AnyExtractor; +}): AnyExtractor; + +const myUnion = unionType([identifierExtractor, stringExtractor]); +>myUnion : AnyExtractor<{ node: Identifier; kind: "identifier"; value: string; } | { node: StringLiteral; kind: "string"; value: string; }> +>unionType([identifierExtractor, stringExtractor]) : AnyExtractor<{ node: Identifier; kind: "identifier"; value: string; } | { node: StringLiteral; kind: "string"; value: string; }> +>unionType : (parsers: { [K in keyof Result]: AnyExtractor; }) => AnyExtractor +>[identifierExtractor, stringExtractor] : (Extractor | Extractor)[] +>identifierExtractor : Extractor +>stringExtractor : Extractor + diff --git a/tests/baselines/reference/stringMatchAll.types b/tests/baselines/reference/stringMatchAll.types index 59c112f5016..9386da13c84 100644 --- a/tests/baselines/reference/stringMatchAll.types +++ b/tests/baselines/reference/stringMatchAll.types @@ -2,23 +2,23 @@ === stringMatchAll.ts === const matches = "matchAll".matchAll(/\w/g); ->matches : IterableIterator ->"matchAll".matchAll(/\w/g) : IterableIterator ->"matchAll".matchAll : (regexp: RegExp) => IterableIterator +>matches : IterableIterator +>"matchAll".matchAll(/\w/g) : IterableIterator +>"matchAll".matchAll : (regexp: RegExp) => IterableIterator >"matchAll" : "matchAll" ->matchAll : (regexp: RegExp) => IterableIterator +>matchAll : (regexp: RegExp) => IterableIterator >/\w/g : RegExp const array = [...matches]; ->array : RegExpMatchArray[] ->[...matches] : RegExpMatchArray[] ->...matches : RegExpMatchArray ->matches : IterableIterator +>array : RegExpExecArray[] +>[...matches] : RegExpExecArray[] +>...matches : RegExpExecArray +>matches : IterableIterator const { index, input } = array[0]; >index : number >input : string ->array[0] : RegExpMatchArray ->array : RegExpMatchArray[] +>array[0] : RegExpExecArray +>array : RegExpExecArray[] >0 : 0 diff --git a/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts b/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts new file mode 100644 index 00000000000..8c1ea320962 --- /dev/null +++ b/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts @@ -0,0 +1,28 @@ +// @strict: true +// @noEmit: true + +interface Action { + new (ctx: TContext): void; +} + +declare class AssignAction { + constructor(ctx: TContext); +} + +declare function assign( + assigner: (ctx: TContext) => void +): { + new (ctx: TContext): AssignAction; +} + +declare function createMachine(config: { + context: TContext; + entry: Action; +}): void; + +createMachine({ + context: { count: 0 }, + entry: assign((ctx) => { + ctx // { count: number } + }), +}); diff --git a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts new file mode 100644 index 00000000000..e5655497911 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts @@ -0,0 +1,174 @@ +// @strict: true + +type StateConfig = { + entry?: TAction + states?: Record>; +}; + +type StateSchema = { + states?: Record; +}; + +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +checked; + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +foo({x: 1, y: 'foo'}); + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +}); + +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 +}); diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts new file mode 100644 index 00000000000..7618ae65046 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts @@ -0,0 +1,15 @@ +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); \ No newline at end of file diff --git a/tests/cases/compiler/reverseMappedUnionInference.ts b/tests/cases/compiler/reverseMappedUnionInference.ts new file mode 100644 index 00000000000..0f1ffc1c347 --- /dev/null +++ b/tests/cases/compiler/reverseMappedUnionInference.ts @@ -0,0 +1,59 @@ +// @strict: true +// @noEmit: true + +interface AnyExtractor { + matches: (node: any) => boolean; + extract: (node: any) => Result | undefined; +} + +interface Extractor { + matches: (node: unknown) => node is T; + extract: (node: T) => Result | undefined; +} + +declare function createExtractor(params: { + matcher: (node: unknown) => node is T; + extract: (node: T) => Result; +}): Extractor; + +interface Identifier { + kind: "identifier"; + name: string; +} + +declare function isIdentifier(node: unknown): node is Identifier; + +const identifierExtractor = createExtractor({ + matcher: isIdentifier, + extract: (node) => { + return { + node, + kind: "identifier" as const, + value: node.name, + }; + }, +}); + +interface StringLiteral { + kind: "stringLiteral"; + value: string; +} + +declare function isStringLiteral(node: unknown): node is StringLiteral; + +const stringExtractor = createExtractor({ + matcher: isStringLiteral, + extract: (node) => { + return { + node, + kind: "string" as const, + value: node.value, + }; + }, +}); + +declare function unionType(parsers: { + [K in keyof Result]: AnyExtractor; +}): AnyExtractor; + +const myUnion = unionType([identifierExtractor, stringExtractor]); diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts index 4cd9047581f..2d6f92b9bde 100644 --- a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts @@ -1,11 +1,22 @@ // @target: es6 -class C { +class C1 { static staticProp = 10; - get [C.staticProp]() { + get [C1.staticProp]() { return "hello"; } - set [C.staticProp](x: string) { + set [C1.staticProp](x: string) { var y = x; } - [C.staticProp]() { } -} \ No newline at end of file + [C1.staticProp]() { } +} + +(class C2 { + static staticProp = 10; + get [C2.staticProp]() { + return "hello"; + } + set [C2.staticProp](x: string) { + var y = x; + } + [C2.staticProp]() { } +}) diff --git a/tests/cases/conformance/jsdoc/callbackTag4.ts b/tests/cases/conformance/jsdoc/callbackTag4.ts new file mode 100644 index 00000000000..a5ac356aedd --- /dev/null +++ b/tests/cases/conformance/jsdoc/callbackTag4.ts @@ -0,0 +1,19 @@ +// @allowJs: true +// @checkJs: true +// @strict: true +// @noEmit: true +// @filename: ./a.js + +/** + * @callback C + * @this {{ a: string, b: number }} + * @param {string} a + * @param {number} b + * @returns {boolean} + */ + +/** @type {C} */ +const cb = function (a, b) { + this + return true +} diff --git a/tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts b/tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts index ba0222660b8..9256a4541fe 100644 --- a/tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts +++ b/tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts @@ -29,7 +29,8 @@ type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | numbe type DoubleProp = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] } type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number } type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' -type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` +type TD3 = keyof DoubleProp; // keyof DoubleProp +type TD4 = TD3<{ a: string, b: number }>; // 'a1' | 'a2' | 'b1' | 'b2' // Repro from #40619 @@ -152,3 +153,26 @@ type TN2 = keyof { [P in keyof T as 'a' extends P ? 'x' : 'y']: string }; type TN3 = keyof { [P in keyof T as Exclude, 'b'>, 'a'>]: string }; type TN4 = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string }; type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string }; + +// repro from https://github.com/microsoft/TypeScript/issues/55129 +type Fruit = + | { + name: "apple"; + color: "red"; + } + | { + name: "banana"; + color: "yellow"; + } + | { + name: "orange"; + color: "orange"; + }; +type Result1 = { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +}; +type Result2 = keyof { + [Key in T as `${Key['name']}:${Key['color']}`]: unknown +} +type Test1 = keyof Result1 // "apple:red" | "banana:yellow" | "orange:orange" +type Test2 = Result2 // "apple:red" | "banana:yellow" | "orange:orange" diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts index 4f3e7ecda0d..4f747be593f 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts @@ -71,3 +71,40 @@ function f14(a: AList4, b: BList4) { a = b; b = a; // Error } + +// Repro from #51620 + +type Bivar = { set(value: T): void } + +declare let bu: Bivar; +declare let bs: Bivar; +bu = bs; +bs = bu; + +declare let bfu: Bivar<(x: unknown) => void>; +declare let bfs: Bivar<(x: string) => void>; +bfu = bfs; +bfs = bfu; + +type Bivar1 = { set(value: T): void } +type Bivar2 = { set(value: T): void } + +declare let b1fu: Bivar1<(x: unknown) => void>; +declare let b2fs: Bivar2<(x: string) => void>; +b1fu = b2fs; +b2fs = b1fu; + +type SetLike = { set(value: T): void, get(): T } + +declare let sx: SetLike1<(x: unknown) => void>; +declare let sy: SetLike1<(x: string) => void>; +sx = sy; // Error +sy = sx; + +type SetLike1 = { set(value: T): void, get(): T } +type SetLike2 = { set(value: T): void, get(): T } + +declare let s1: SetLike1<(x: unknown) => void>; +declare let s2: SetLike2<(x: string) => void>; +s1 = s2; // Error +s2 = s1;