commit
f437c8f318
|
@ -1308,6 +1308,7 @@ namespace ts {
|
|||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.MappedType:
|
||||
return ContainerFlags.IsContainer | ContainerFlags.HasLocals;
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
|
@ -1427,6 +1428,7 @@ namespace ts {
|
|||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.MappedType:
|
||||
// All the children of these container types are never visible through another
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
// they're only accessed 'lexically' (i.e. from code that exists underneath
|
||||
|
@ -1977,9 +1979,10 @@ namespace ts {
|
|||
case SyntaxKind.JSDocFunctionType:
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
return bindAnonymousDeclaration(<TypeLiteralNode>node, SymbolFlags.TypeLiteral, "__type");
|
||||
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, "__type");
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
|
@ -3153,6 +3156,7 @@ namespace ts {
|
|||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.LiteralType:
|
||||
// Types and signatures are TypeScript syntax, and exclude all other facts.
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
|
|
|
@ -2248,7 +2248,7 @@ namespace ts {
|
|||
// The specified symbol flags need to be reinterpreted as type flags
|
||||
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
|
||||
}
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && (getObjectFlags(type) & ObjectFlags.Anonymous || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol &&
|
||||
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
|
||||
const typeArguments = type.aliasTypeArguments;
|
||||
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
|
||||
|
@ -2256,7 +2256,7 @@ namespace ts {
|
|||
else if (type.flags & TypeFlags.UnionOrIntersection) {
|
||||
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, nextFlags);
|
||||
}
|
||||
else if (getObjectFlags(type) & ObjectFlags.Anonymous) {
|
||||
else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) {
|
||||
writeAnonymousType(<ObjectType>type, nextFlags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringOrNumberLiteral) {
|
||||
|
@ -2475,6 +2475,13 @@ namespace ts {
|
|||
}
|
||||
|
||||
function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) {
|
||||
if (type.objectFlags & ObjectFlags.Mapped) {
|
||||
if (getConstraintTypeFromMappedType(<MappedType>type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) {
|
||||
writeMappedType(<MappedType>type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
|
||||
if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
|
||||
|
@ -2553,7 +2560,34 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeMappedType(type: MappedType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenBraceToken);
|
||||
writer.writeLine();
|
||||
writer.increaseIndent();
|
||||
if (type.declaration.readonlyToken) {
|
||||
writeKeyword(writer, SyntaxKind.ReadonlyKeyword);
|
||||
writeSpace(writer);
|
||||
}
|
||||
writePunctuation(writer, SyntaxKind.OpenBracketToken);
|
||||
appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer);
|
||||
writeSpace(writer);
|
||||
writeKeyword(writer, SyntaxKind.InKeyword);
|
||||
writeSpace(writer);
|
||||
writeType(getConstraintTypeFromMappedType(type), TypeFormatFlags.None);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
if (type.declaration.questionToken) {
|
||||
writePunctuation(writer, SyntaxKind.QuestionToken);
|
||||
}
|
||||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
writeSpace(writer);
|
||||
writeType(getTemplateTypeFromMappedType(type), TypeFormatFlags.None);
|
||||
writePunctuation(writer, SyntaxKind.SemicolonToken);
|
||||
writer.writeLine();
|
||||
writer.decreaseIndent();
|
||||
writePunctuation(writer, SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
}
|
||||
|
||||
function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags) {
|
||||
const targetSymbol = getTargetSymbol(symbol);
|
||||
|
@ -3694,7 +3728,7 @@ namespace ts {
|
|||
function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[]): Signature[] {
|
||||
let signatures = getConstructorsForTypeArguments(type, typeArgumentNodes);
|
||||
if (typeArgumentNodes) {
|
||||
const typeArguments = map(typeArgumentNodes, getTypeFromTypeNodeNoAlias);
|
||||
const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode);
|
||||
signatures = map(signatures, sig => getSignatureInstantiation(sig, typeArguments));
|
||||
}
|
||||
return signatures;
|
||||
|
@ -3905,7 +3939,6 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
|
||||
const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
|
||||
let declaration: JSDocTypedefTag | TypeAliasDeclaration = <JSDocTypedefTag>getDeclarationOfKind(symbol, SyntaxKind.JSDocTypedefTag);
|
||||
let type: Type;
|
||||
if (declaration) {
|
||||
|
@ -3918,16 +3951,17 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
|
||||
type = getTypeFromTypeNode(declaration.type, symbol, typeParameters);
|
||||
type = getTypeFromTypeNode(declaration.type);
|
||||
}
|
||||
|
||||
if (popTypeResolution()) {
|
||||
links.typeParameters = typeParameters;
|
||||
const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
|
||||
if (typeParameters) {
|
||||
// Initialize the instantiation cache for generic type aliases. The declared type corresponds to
|
||||
// an instantiation of the type alias with the type parameters supplied as type arguments.
|
||||
links.typeParameters = typeParameters;
|
||||
links.instantiations = createMap<Type>();
|
||||
links.instantiations[getTypeListId(links.typeParameters)] = type;
|
||||
links.instantiations[getTypeListId(typeParameters)] = type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4263,7 +4297,7 @@ namespace ts {
|
|||
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
|
||||
}
|
||||
const baseTypeNode = getBaseTypeNodeOfClass(classType);
|
||||
const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNodeNoAlias);
|
||||
const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode);
|
||||
const typeArgCount = typeArguments ? typeArguments.length : 0;
|
||||
const result: Signature[] = [];
|
||||
for (const baseSig of baseSignatures) {
|
||||
|
@ -4450,6 +4484,80 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/** Resolve the members of a mapped type { [P in K]: T } */
|
||||
function resolveMappedTypeMembers(type: MappedType) {
|
||||
const members: SymbolTable = createMap<Symbol>();
|
||||
let stringIndexInfo: IndexInfo;
|
||||
let numberIndexInfo: IndexInfo;
|
||||
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
|
||||
// and T as the template type.
|
||||
const typeParameter = getTypeParameterFromMappedType(type);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const templateType = getTemplateTypeFromMappedType(type);
|
||||
const isReadonly = !!type.declaration.readonlyToken;
|
||||
const isOptional = !!type.declaration.questionToken;
|
||||
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
|
||||
// if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
|
||||
// Finally, iterate over the constituents of the resulting iteration type.
|
||||
const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentType(constraintType) : constraintType;
|
||||
const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
|
||||
forEachType(iterationType, t => {
|
||||
// Create a mapper from T to the current iteration type constituent. Then, if the
|
||||
// mapped type is itself an instantiated type, combine the iteration mapper with the
|
||||
// instantiation mapper.
|
||||
const iterationMapper = createUnaryTypeMapper(typeParameter, t);
|
||||
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
|
||||
const propType = instantiateType(templateType, templateMapper);
|
||||
// If the current iteration type constituent is a literal type, create a property.
|
||||
// Otherwise, for type string create a string index signature and for type number
|
||||
// create a numeric index signature.
|
||||
if (t.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
|
||||
const propName = (<LiteralType>t).text;
|
||||
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
|
||||
prop.type = addOptionality(propType, isOptional);
|
||||
prop.isReadonly = isReadonly;
|
||||
members[propName] = prop;
|
||||
}
|
||||
else if (t.flags & TypeFlags.String) {
|
||||
stringIndexInfo = createIndexInfo(propType, isReadonly);
|
||||
}
|
||||
else if (t.flags & TypeFlags.Number) {
|
||||
numberIndexInfo = createIndexInfo(propType, isReadonly);
|
||||
}
|
||||
});
|
||||
// If we created both a string and a numeric string index signature, and if the two index
|
||||
// signatures have identical types, discard the redundant numeric index signature.
|
||||
if (stringIndexInfo && numberIndexInfo && isTypeIdenticalTo(stringIndexInfo.type, numberIndexInfo.type)) {
|
||||
numberIndexInfo = undefined;
|
||||
}
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
}
|
||||
|
||||
function getTypeParameterFromMappedType(type: MappedType) {
|
||||
return type.typeParameter ||
|
||||
(type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
|
||||
}
|
||||
|
||||
function getConstraintTypeFromMappedType(type: MappedType) {
|
||||
return type.constraintType ||
|
||||
(type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType);
|
||||
}
|
||||
|
||||
function getTemplateTypeFromMappedType(type: MappedType) {
|
||||
return type.templateType ||
|
||||
(type.templateType = type.declaration.type ?
|
||||
instantiateType(getTypeFromTypeNode(type.declaration.type), type.mapper || identityMapper) :
|
||||
unknownType);
|
||||
}
|
||||
|
||||
function isGenericMappedType(type: Type) {
|
||||
if (getObjectFlags(type) & ObjectFlags.Mapped) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>type);
|
||||
return !!(constraintType.flags & (TypeFlags.TypeParameter | TypeFlags.Index));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
|
||||
if (!(<ResolvedType>type).members) {
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
|
@ -4462,6 +4570,9 @@ namespace ts {
|
|||
else if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
|
||||
resolveAnonymousTypeMembers(<AnonymousType>type);
|
||||
}
|
||||
else if ((<MappedType>type).objectFlags & ObjectFlags.Mapped) {
|
||||
resolveMappedTypeMembers(<MappedType>type);
|
||||
}
|
||||
}
|
||||
else if (type.flags & TypeFlags.Union) {
|
||||
resolveUnionTypeMembers(<UnionType>type);
|
||||
|
@ -5212,7 +5323,7 @@ namespace ts {
|
|||
// In a type reference, the outer type parameters of the referenced class or interface are automatically
|
||||
// supplied as type arguments and the type reference only specifies arguments for the local type parameters
|
||||
// of the class or interface.
|
||||
return createTypeReference(<GenericType>type, concatenate(type.outerTypeParameters, map(node.typeArguments, getTypeFromTypeNodeNoAlias)));
|
||||
return createTypeReference(<GenericType>type, concatenate(type.outerTypeParameters, map(node.typeArguments, getTypeFromTypeNode)));
|
||||
}
|
||||
if (node.typeArguments) {
|
||||
error(node, Diagnostics.Type_0_is_not_generic, typeToString(type));
|
||||
|
@ -5221,21 +5332,27 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[]): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters;
|
||||
const id = getTypeListId(typeArguments);
|
||||
return links.instantiations[id] || (links.instantiations[id] = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, typeArguments)));
|
||||
}
|
||||
|
||||
// Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
|
||||
// references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
|
||||
// declared type. Instantiations are cached using the type identities of the type arguments as the key.
|
||||
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters;
|
||||
const typeParameters = getSymbolLinks(symbol).typeParameters;
|
||||
if (typeParameters) {
|
||||
if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
|
||||
error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length);
|
||||
return unknownType;
|
||||
}
|
||||
const typeArguments = map(node.typeArguments, getTypeFromTypeNodeNoAlias);
|
||||
const id = getTypeListId(typeArguments);
|
||||
return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
|
||||
const typeArguments = map(node.typeArguments, getTypeFromTypeNode);
|
||||
return getTypeAliasInstantiation(symbol, typeArguments);
|
||||
}
|
||||
if (node.typeArguments) {
|
||||
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
|
||||
|
@ -5486,7 +5603,7 @@ namespace ts {
|
|||
function getTypeFromTupleTypeNode(node: TupleTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNodeNoAlias));
|
||||
links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNode));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
@ -5676,10 +5793,11 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function getTypeFromUnionTypeNode(node: UnionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNodeNoAlias), /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false,
|
||||
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
@ -5747,10 +5865,11 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNodeNoAlias), aliasSymbol, aliasTypeArguments);
|
||||
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode),
|
||||
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
@ -5764,7 +5883,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getLiteralTypeFromPropertyName(prop: Symbol) {
|
||||
return startsWith(prop.name, "__@") ? neverType : getLiteralTypeForText(TypeFlags.StringLiteral, unescapeIdentifier(prop.name));
|
||||
return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || startsWith(prop.name, "__@") ?
|
||||
neverType :
|
||||
getLiteralTypeForText(TypeFlags.StringLiteral, unescapeIdentifier(prop.name));
|
||||
}
|
||||
|
||||
function getLiteralTypeFromPropertyNames(type: Type) {
|
||||
|
@ -5781,7 +5902,7 @@ namespace ts {
|
|||
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getIndexType(getTypeFromTypeNodeNoAlias(node.type));
|
||||
links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
@ -5863,10 +5984,8 @@ namespace ts {
|
|||
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {
|
||||
if (indexType.flags & TypeFlags.TypeParameter) {
|
||||
if (!isTypeAssignableTo(getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType, getIndexType(objectType))) {
|
||||
if (accessNode) {
|
||||
error(accessNode, Diagnostics.Type_0_is_not_constrained_to_keyof_1, typeToString(indexType), typeToString(objectType));
|
||||
}
|
||||
if (accessNode && !isTypeAssignableTo(getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType, getIndexType(objectType))) {
|
||||
error(accessNode, Diagnostics.Type_0_is_not_constrained_to_keyof_1, typeToString(indexType), typeToString(objectType));
|
||||
return unknownType;
|
||||
}
|
||||
return getIndexedAccessTypeForTypeParameter(objectType, <TypeParameter>indexType);
|
||||
|
@ -5889,28 +6008,50 @@ namespace ts {
|
|||
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getIndexedAccessType(getTypeFromTypeNodeNoAlias(node.objectType), getTypeFromTypeNodeNoAlias(node.indexType), node);
|
||||
links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node);
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getTypeFromMappedTypeNode(node: MappedTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const type = <MappedType>createObjectType(ObjectFlags.Mapped, node.symbol);
|
||||
type.declaration = node;
|
||||
type.aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
|
||||
links.resolvedType = type;
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: TypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
// Deferred resolution of members is handled by resolveObjectTypeMembers
|
||||
if (isEmpty(node.symbol.members) && !aliasSymbol && !aliasTypeArguments) {
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
if (isEmpty(node.symbol.members) && !aliasSymbol) {
|
||||
links.resolvedType = emptyTypeLiteralType;
|
||||
}
|
||||
else {
|
||||
const type = createObjectType(ObjectFlags.Anonymous, node.symbol);
|
||||
type.aliasSymbol = aliasSymbol;
|
||||
type.aliasTypeArguments = aliasTypeArguments;
|
||||
type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
|
||||
links.resolvedType = type;
|
||||
}
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getAliasSymbolForTypeNode(node: TypeNode) {
|
||||
return node.parent.kind === SyntaxKind.TypeAliasDeclaration ? getSymbolOfNode(node.parent) : undefined;
|
||||
}
|
||||
|
||||
function getAliasTypeArgumentsForTypeNode(node: TypeNode) {
|
||||
const symbol = getAliasSymbolForTypeNode(node);
|
||||
return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the source of spread types are object literals, which are not binary,
|
||||
* this function should be called in a left folding style, with left = previous result of getSpreadType
|
||||
|
@ -6020,7 +6161,7 @@ namespace ts {
|
|||
function getTypeFromJSDocTupleType(node: JSDocTupleType): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const types = map(node.types, getTypeFromTypeNodeNoAlias);
|
||||
const types = map(node.types, getTypeFromTypeNode);
|
||||
links.resolvedType = createTupleType(types);
|
||||
}
|
||||
return links.resolvedType;
|
||||
|
@ -6047,11 +6188,7 @@ namespace ts {
|
|||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeNodeNoAlias(type: TypeNode) {
|
||||
return getTypeFromTypeNode(type, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined);
|
||||
}
|
||||
|
||||
function getTypeFromTypeNode(node: TypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getTypeFromTypeNode(node: TypeNode): Type {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.JSDocAllType:
|
||||
|
@ -6102,9 +6239,9 @@ namespace ts {
|
|||
return getTypeFromTupleTypeNode(<TupleTypeNode>node);
|
||||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.JSDocUnionType:
|
||||
return getTypeFromUnionTypeNode(<UnionTypeNode>node, aliasSymbol, aliasTypeArguments);
|
||||
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
|
||||
case SyntaxKind.IntersectionType:
|
||||
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node, aliasSymbol, aliasTypeArguments);
|
||||
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
case SyntaxKind.JSDocNullableType:
|
||||
case SyntaxKind.JSDocNonNullableType:
|
||||
|
@ -6119,11 +6256,13 @@ namespace ts {
|
|||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node, aliasSymbol, aliasTypeArguments);
|
||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
case SyntaxKind.TypeOperator:
|
||||
return getTypeFromTypeOperatorNode(<TypeOperatorNode>node);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
|
||||
case SyntaxKind.MappedType:
|
||||
return getTypeFromMappedTypeNode(<MappedTypeNode>node);
|
||||
// This function assumes that an identifier or qualified name is a type expression
|
||||
// Callers should first ensure this by calling isTypeNode
|
||||
case SyntaxKind.Identifier:
|
||||
|
@ -6158,6 +6297,11 @@ namespace ts {
|
|||
return instantiateList(signatures, mapper, instantiateSignature);
|
||||
}
|
||||
|
||||
function instantiateCached<T extends Type>(type: T, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T {
|
||||
const instantiations = mapper.instantiations || (mapper.instantiations = []);
|
||||
return <T>instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper));
|
||||
}
|
||||
|
||||
function createUnaryTypeMapper(source: Type, target: Type): TypeMapper {
|
||||
return t => t === source ? target : t;
|
||||
}
|
||||
|
@ -6295,23 +6439,21 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): ObjectType {
|
||||
if (mapper.instantiations) {
|
||||
const cachedType = <ObjectType>mapper.instantiations[type.id];
|
||||
if (cachedType) {
|
||||
return cachedType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mapper.instantiations = [];
|
||||
}
|
||||
// Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType {
|
||||
const result = <AnonymousType>createObjectType(ObjectFlags.Anonymous | ObjectFlags.Instantiated, type.symbol);
|
||||
result.target = type;
|
||||
result.mapper = mapper;
|
||||
result.target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type;
|
||||
result.mapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
result.aliasSymbol = type.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
return result;
|
||||
}
|
||||
|
||||
function instantiateMappedType(type: MappedType, mapper: TypeMapper): MappedType {
|
||||
const result = <MappedType>createObjectType(ObjectFlags.Mapped | ObjectFlags.Instantiated, type.symbol);
|
||||
result.declaration = type.declaration;
|
||||
result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
result.aliasSymbol = type.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
mapper.instantiations[type.id] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -6367,41 +6509,80 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isTopLevelTypeAlias(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations.length) {
|
||||
const parentKind = symbol.declarations[0].parent.kind;
|
||||
return parentKind === SyntaxKind.SourceFile || parentKind === SyntaxKind.ModuleBlock;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function instantiateType(type: Type, mapper: TypeMapper): Type {
|
||||
if (type && mapper !== identityMapper) {
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
return mapper(<TypeParameter>type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
|
||||
// If the anonymous type originates in a declaration of a function, method, class, or
|
||||
// interface, in an object type literal, or in an object literal expression, we may need
|
||||
// to instantiate the type because it might reference a type parameter. We skip instantiation
|
||||
// if none of the type parameters that are in scope in the type's declaration are mapped by
|
||||
// the given mapper, however we can only do that analysis if the type isn't itself an
|
||||
// instantiation.
|
||||
return type.symbol &&
|
||||
type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) &&
|
||||
((<ObjectType>type).objectFlags & ObjectFlags.Instantiated || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ?
|
||||
instantiateAnonymousType(<AnonymousType>type, mapper) : type;
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
// If we are instantiating a type that has a top-level type alias, obtain the instantiation through
|
||||
// the type alias instead in order to share instantiations for the same type arguments. This can
|
||||
// dramatically reduce the number of structurally identical types we generate. Note that we can only
|
||||
// perform this optimization for top-level type aliases. Consider:
|
||||
//
|
||||
// function f1<T>(x: T) {
|
||||
// type Foo<X> = { x: X, t: T };
|
||||
// let obj: Foo<T> = { x: x };
|
||||
// return obj;
|
||||
// }
|
||||
// function f2<U>(x: U) { return f1(x); }
|
||||
// let z = f2(42);
|
||||
//
|
||||
// Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo<X>
|
||||
// equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo<X>'s
|
||||
// cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been
|
||||
// instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form.
|
||||
if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) {
|
||||
if (type.aliasTypeArguments) {
|
||||
return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
return instantiateTypeNoAlias(type, mapper);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function instantiateTypeNoAlias(type: Type, mapper: TypeMapper): Type {
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
return mapper(<TypeParameter>type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
|
||||
// If the anonymous type originates in a declaration of a function, method, class, or
|
||||
// interface, in an object type literal, or in an object literal expression, we may need
|
||||
// to instantiate the type because it might reference a type parameter. We skip instantiation
|
||||
// if none of the type parameters that are in scope in the type's declaration are mapped by
|
||||
// the given mapper, however we can only do that analysis if the type isn't itself an
|
||||
// instantiation.
|
||||
return type.symbol &&
|
||||
type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) &&
|
||||
((<ObjectType>type).objectFlags & ObjectFlags.Instantiated || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ?
|
||||
instantiateCached(type, mapper, instantiateAnonymousType) : type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Mapped) {
|
||||
return instantiateCached(type, mapper, instantiateMappedType);
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -6890,6 +7071,13 @@ namespace ts {
|
|||
|
||||
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
if (source.flags & TypeFlags.Index) {
|
||||
// A keyof T is related to a union type containing both string and number
|
||||
if (maybeTypeOfKind(target, TypeFlags.String) && maybeTypeOfKind(target, TypeFlags.Number)) {
|
||||
return Ternary.True;
|
||||
}
|
||||
}
|
||||
|
||||
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
|
@ -6962,6 +7150,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Index) {
|
||||
// A keyof S is related to a keyof T if T is related to S.
|
||||
if (source.flags & TypeFlags.Index) {
|
||||
if (result = isRelatedTo((<IndexType>target).type, (<IndexType>source).type, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Given a type parameter T with a constraint C, a type S is assignable to
|
||||
// keyof T if S is assignable to keyof C.
|
||||
const constraint = getConstraintOfTypeParameter((<IndexType>target).type);
|
||||
|
@ -6996,18 +7190,29 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
}
|
||||
// Even if relationship doesn't hold for unions, intersections, or generic type references,
|
||||
// it may hold in a structural comparison.
|
||||
const apparentSource = getApparentType(source);
|
||||
// In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
|
||||
// to X. Failing both of those we want to check if the aggregation of A and B's members structurally
|
||||
// relates to X. Thus, we include intersection types on the source side here.
|
||||
if (apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) {
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive);
|
||||
if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
if (isGenericMappedType(target)) {
|
||||
// A type [P in S]: X is related to a type [P in T]: Y if T is related to S and X is related to Y.
|
||||
if (isGenericMappedType(source)) {
|
||||
if ((result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) &&
|
||||
(result = isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target), reportErrors))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Even if relationship doesn't hold for unions, intersections, or generic type references,
|
||||
// it may hold in a structural comparison.
|
||||
const apparentSource = getApparentType(source);
|
||||
// In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
|
||||
// to X. Failing both of those we want to check if the aggregation of A and B's members structurally
|
||||
// relates to X. Thus, we include intersection types on the source side here.
|
||||
if (apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) {
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive);
|
||||
if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8097,9 +8302,11 @@ namespace ts {
|
|||
// we perform type inference (i.e. a type parameter of a generic function). We cache
|
||||
// results for union and intersection types for performance reasons.
|
||||
function couldContainTypeParameters(type: Type): boolean {
|
||||
const objectFlags = getObjectFlags(type);
|
||||
return !!(type.flags & TypeFlags.TypeParameter ||
|
||||
getObjectFlags(type) & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
|
||||
getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
|
||||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
|
||||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
|
||||
objectFlags & ObjectFlags.Mapped ||
|
||||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeParameters(<UnionOrIntersectionType>type));
|
||||
}
|
||||
|
||||
|
@ -8136,6 +8343,16 @@ namespace ts {
|
|||
if (!couldContainTypeParameters(target)) {
|
||||
return;
|
||||
}
|
||||
if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
// Simply infer from source type arguments to target type arguments.
|
||||
const sourceTypes = source.aliasTypeArguments;
|
||||
const targetTypes = target.aliasTypeArguments;
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
// Source and target are both unions or both intersections. If source and target
|
||||
|
@ -8247,6 +8464,19 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
|
||||
if (getObjectFlags(source) & ObjectFlags.Mapped) {
|
||||
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
|
||||
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
return;
|
||||
}
|
||||
if (constraintType.flags & TypeFlags.TypeParameter) {
|
||||
inferFromTypes(getIndexType(source), constraintType);
|
||||
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
return;
|
||||
}
|
||||
}
|
||||
source = getApparentType(source);
|
||||
if (source.flags & TypeFlags.Object) {
|
||||
if (isInProcess(source, target)) {
|
||||
|
@ -8855,6 +9085,10 @@ namespace ts {
|
|||
return containsType(target.types, source);
|
||||
}
|
||||
|
||||
function forEachType<T>(type: Type, f: (t: Type) => T): T {
|
||||
return type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, f) : f(type);
|
||||
}
|
||||
|
||||
function filterType(type: Type, f: (t: Type) => boolean): Type {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const types = (<UnionType>type).types;
|
||||
|
@ -12694,7 +12928,7 @@ namespace ts {
|
|||
else if (candidateForTypeArgumentError) {
|
||||
if (!isTaggedTemplate && !isDecorator && typeArguments) {
|
||||
const typeArguments = (<CallExpression>node).typeArguments;
|
||||
checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNodeNoAlias), /*reportErrors*/ true, headMessage);
|
||||
checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, headMessage);
|
||||
}
|
||||
else {
|
||||
Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0);
|
||||
|
@ -12725,7 +12959,7 @@ namespace ts {
|
|||
for (let candidate of candidates) {
|
||||
if (hasCorrectArity(node, args, candidate)) {
|
||||
if (candidate.typeParameters && typeArguments) {
|
||||
candidate = getSignatureInstantiation(candidate, map(typeArguments, getTypeFromTypeNodeNoAlias));
|
||||
candidate = getSignatureInstantiation(candidate, map(typeArguments, getTypeFromTypeNode));
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
@ -12761,7 +12995,7 @@ namespace ts {
|
|||
if (candidate.typeParameters) {
|
||||
let typeArgumentTypes: Type[];
|
||||
if (typeArguments) {
|
||||
typeArgumentTypes = map(typeArguments, getTypeFromTypeNodeNoAlias);
|
||||
typeArgumentTypes = map(typeArguments, getTypeFromTypeNode);
|
||||
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false);
|
||||
}
|
||||
else {
|
||||
|
@ -15228,7 +15462,7 @@ namespace ts {
|
|||
const constraint = getConstraintOfTypeParameter(typeParameters[i]);
|
||||
if (constraint) {
|
||||
if (!typeArguments) {
|
||||
typeArguments = map(typeArgumentNodes, getTypeFromTypeNodeNoAlias);
|
||||
typeArguments = map(typeArgumentNodes, getTypeFromTypeNode);
|
||||
mapper = createTypeMapper(typeParameters, typeArguments);
|
||||
}
|
||||
const typeArgument = typeArguments[i];
|
||||
|
@ -15297,6 +15531,15 @@ namespace ts {
|
|||
getTypeFromIndexedAccessTypeNode(node);
|
||||
}
|
||||
|
||||
function checkMappedType(node: MappedTypeNode) {
|
||||
checkSourceElement(node.typeParameter);
|
||||
checkSourceElement(node.type);
|
||||
const type = <MappedType>getTypeFromMappedTypeNode(node);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentTypeOfTypeParameter(<TypeParameter>constraintType) : constraintType;
|
||||
checkTypeAssignableTo(keyType, stringOrNumberType, node.typeParameter.constraint);
|
||||
}
|
||||
|
||||
function isPrivateWithinAmbient(node: Node): boolean {
|
||||
return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node);
|
||||
}
|
||||
|
@ -18545,6 +18788,8 @@ namespace ts {
|
|||
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return checkIndexedAccessType(<IndexedAccessTypeNode>node);
|
||||
case SyntaxKind.MappedType:
|
||||
return checkMappedType(<MappedTypeNode>node);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return checkFunctionDeclaration(<FunctionDeclaration>node);
|
||||
case SyntaxKind.Block:
|
||||
|
|
|
@ -416,7 +416,9 @@ namespace ts {
|
|||
case SyntaxKind.TypeOperator:
|
||||
return emitTypeOperator(<TypeOperatorNode>type);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return emitPropertyAccessType(<IndexedAccessTypeNode>type);
|
||||
return emitIndexedAccessType(<IndexedAccessTypeNode>type);
|
||||
case SyntaxKind.MappedType:
|
||||
return emitMappedType(<MappedTypeNode>type);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return emitSignatureDeclarationWithJsDocComments(<FunctionOrConstructorTypeNode>type);
|
||||
|
@ -516,13 +518,39 @@ namespace ts {
|
|||
emitType(type.type);
|
||||
}
|
||||
|
||||
function emitPropertyAccessType(node: IndexedAccessTypeNode) {
|
||||
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
|
||||
emitType(node.objectType);
|
||||
write("[");
|
||||
emitType(node.indexType);
|
||||
write("]");
|
||||
}
|
||||
|
||||
function emitMappedType(node: MappedTypeNode) {
|
||||
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
write("{");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
if (node.readonlyToken) {
|
||||
write("readonly ");
|
||||
}
|
||||
write("[");
|
||||
writeEntityName(node.typeParameter.name);
|
||||
write(" in ");
|
||||
emitType(node.typeParameter.constraint);
|
||||
write("]");
|
||||
if (node.questionToken) {
|
||||
write("?");
|
||||
}
|
||||
write(": ");
|
||||
emitType(node.type);
|
||||
write(";");
|
||||
writeLine();
|
||||
decreaseIndent();
|
||||
write("}");
|
||||
enclosingDeclaration = prevEnclosingDeclaration;
|
||||
}
|
||||
|
||||
function emitTypeLiteral(type: TypeLiteralNode) {
|
||||
write("{");
|
||||
if (type.members.length) {
|
||||
|
|
|
@ -606,7 +606,9 @@ const _super = (function (geti, seti) {
|
|||
case SyntaxKind.TypeOperator:
|
||||
return emitTypeOperator(<TypeOperatorNode>node);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return emitPropertyAccessType(<IndexedAccessTypeNode>node);
|
||||
return emitIndexedAccessType(<IndexedAccessTypeNode>node);
|
||||
case SyntaxKind.MappedType:
|
||||
return emitMappedType(<MappedTypeNode>node);
|
||||
case SyntaxKind.LiteralType:
|
||||
return emitLiteralType(<LiteralTypeNode>node);
|
||||
|
||||
|
@ -1109,13 +1111,36 @@ const _super = (function (geti, seti) {
|
|||
emit(node.type);
|
||||
}
|
||||
|
||||
function emitPropertyAccessType(node: IndexedAccessTypeNode) {
|
||||
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
|
||||
emit(node.objectType);
|
||||
write("[");
|
||||
emit(node.indexType);
|
||||
write("]");
|
||||
}
|
||||
|
||||
function emitMappedType(node: MappedTypeNode) {
|
||||
write("{");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
if (node.readonlyToken) {
|
||||
write("readonly ");
|
||||
}
|
||||
write("[");
|
||||
emit(node.typeParameter.name);
|
||||
write(" in ");
|
||||
emit(node.typeParameter.constraint);
|
||||
write("]");
|
||||
if (node.questionToken) {
|
||||
write("?");
|
||||
}
|
||||
write(": ");
|
||||
emit(node.type);
|
||||
write(";");
|
||||
writeLine();
|
||||
decreaseIndent();
|
||||
write("}");
|
||||
}
|
||||
|
||||
function emitLiteralType(node: LiteralTypeNode) {
|
||||
emitExpression(node.literal);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,11 @@ namespace ts {
|
|||
case SyntaxKind.IndexedAccessType:
|
||||
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
|
||||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
|
||||
case SyntaxKind.MappedType:
|
||||
return visitNode(cbNode, (<MappedTypeNode>node).readonlyToken) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).typeParameter) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).questionToken) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).type);
|
||||
case SyntaxKind.LiteralType:
|
||||
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
|
@ -2422,6 +2427,36 @@ namespace ts {
|
|||
return members;
|
||||
}
|
||||
|
||||
function isStartOfMappedType() {
|
||||
nextToken();
|
||||
if (token() === SyntaxKind.ReadonlyKeyword) {
|
||||
nextToken();
|
||||
}
|
||||
return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword;
|
||||
}
|
||||
|
||||
function parseMappedTypeParameter() {
|
||||
const node = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
|
||||
node.name = parseIdentifier();
|
||||
parseExpected(SyntaxKind.InKeyword);
|
||||
node.constraint = parseType();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseMappedType() {
|
||||
const node = <MappedTypeNode>createNode(SyntaxKind.MappedType);
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
node.readonlyToken = parseOptionalToken(SyntaxKind.ReadonlyKeyword);
|
||||
parseExpected(SyntaxKind.OpenBracketToken);
|
||||
node.typeParameter = parseMappedTypeParameter();
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
parseSemicolon();
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTupleType(): TupleTypeNode {
|
||||
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
|
||||
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
|
@ -2495,7 +2530,7 @@ namespace ts {
|
|||
case SyntaxKind.TypeOfKeyword:
|
||||
return parseTypeQuery();
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return parseTypeLiteral();
|
||||
return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
return parseTupleType();
|
||||
case SyntaxKind.OpenParenToken:
|
||||
|
|
|
@ -302,6 +302,7 @@ namespace ts {
|
|||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.LiteralType:
|
||||
// TypeScript type nodes are elided.
|
||||
|
||||
|
@ -1791,6 +1792,7 @@ namespace ts {
|
|||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.TypeOperator:
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
|
|
|
@ -219,6 +219,7 @@ namespace ts {
|
|||
ThisType,
|
||||
TypeOperator,
|
||||
IndexedAccessType,
|
||||
MappedType,
|
||||
LiteralType,
|
||||
// Binding patterns
|
||||
ObjectBindingPattern,
|
||||
|
@ -520,6 +521,7 @@ namespace ts {
|
|||
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
|
||||
export type Modifier
|
||||
= Token<SyntaxKind.AbstractKeyword>
|
||||
|
@ -903,6 +905,14 @@ namespace ts {
|
|||
indexType: TypeNode;
|
||||
}
|
||||
|
||||
export interface MappedTypeNode extends TypeNode, Declaration {
|
||||
kind: SyntaxKind.MappedType;
|
||||
readonlyToken?: ReadonlyToken;
|
||||
typeParameter: TypeParameterDeclaration;
|
||||
questionToken?: QuestionToken;
|
||||
type?: TypeNode;
|
||||
}
|
||||
|
||||
export interface LiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.LiteralType;
|
||||
literal: Expression;
|
||||
|
@ -2501,7 +2511,7 @@ namespace ts {
|
|||
RegularEnum = 0x00000100, // Enum
|
||||
ValueModule = 0x00000200, // Instantiated module
|
||||
NamespaceModule = 0x00000400, // Uninstantiated module
|
||||
TypeLiteral = 0x00000800, // Type Literal
|
||||
TypeLiteral = 0x00000800, // Type Literal or mapped type
|
||||
ObjectLiteral = 0x00001000, // Object Literal
|
||||
Method = 0x00002000, // Method
|
||||
Constructor = 0x00004000, // Constructor
|
||||
|
@ -2780,10 +2790,11 @@ namespace ts {
|
|||
Reference = 1 << 2, // Generic type reference
|
||||
Tuple = 1 << 3, // Synthesized generic tuple type
|
||||
Anonymous = 1 << 4, // Anonymous
|
||||
Instantiated = 1 << 5, // Instantiated anonymous type
|
||||
ObjectLiteral = 1 << 6, // Originates in an object literal
|
||||
EvolvingArray = 1 << 7, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 8, // Object literal pattern with computed properties
|
||||
Mapped = 1 << 5, // Mapped
|
||||
Instantiated = 1 << 6, // Instantiated anonymous or mapped type
|
||||
ObjectLiteral = 1 << 7, // Originates in an object literal
|
||||
EvolvingArray = 1 << 8, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
|
@ -2852,6 +2863,15 @@ namespace ts {
|
|||
mapper?: TypeMapper; // Instantiation mapper
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface MappedType extends ObjectType {
|
||||
declaration: MappedTypeNode;
|
||||
typeParameter?: TypeParameter;
|
||||
constraintType?: Type;
|
||||
templateType?: Type;
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
elementType: Type; // Element expressions of evolving array type
|
||||
finalArrayType?: Type; // Final array type of evolving array type
|
||||
|
|
|
@ -272,11 +272,9 @@ namespace ts.SymbolDisplay {
|
|||
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
displayParts.push(spacePart());
|
||||
addFullSymbolName(symbol);
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(keywordPart(SyntaxKind.InKeyword));
|
||||
displayParts.push(spacePart());
|
||||
if (symbol.parent) {
|
||||
// Class/Interface type parameter
|
||||
addInPrefix();
|
||||
addFullSymbolName(symbol.parent, enclosingDeclaration);
|
||||
writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
|
||||
}
|
||||
|
@ -288,6 +286,7 @@ namespace ts.SymbolDisplay {
|
|||
|
||||
if (declaration) {
|
||||
if (isFunctionLikeKind(declaration.kind)) {
|
||||
addInPrefix();
|
||||
const signature = typeChecker.getSignatureFromDeclaration(<SignatureDeclaration>declaration);
|
||||
if (declaration.kind === SyntaxKind.ConstructSignature) {
|
||||
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
|
||||
|
@ -298,10 +297,11 @@ namespace ts.SymbolDisplay {
|
|||
}
|
||||
addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature));
|
||||
}
|
||||
else {
|
||||
else if (declaration.kind === SyntaxKind.TypeAliasDeclaration) {
|
||||
// Type alias type parameter
|
||||
// For example
|
||||
// type list<T> = T[]; // Both T will go through same code path
|
||||
addInPrefix();
|
||||
displayParts.push(keywordPart(SyntaxKind.TypeKeyword));
|
||||
displayParts.push(spacePart());
|
||||
addFullSymbolName(declaration.symbol);
|
||||
|
@ -439,6 +439,12 @@ namespace ts.SymbolDisplay {
|
|||
}
|
||||
}
|
||||
|
||||
function addInPrefix() {
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(keywordPart(SyntaxKind.InKeyword));
|
||||
displayParts.push(spacePart());
|
||||
}
|
||||
|
||||
function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) {
|
||||
const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
|
||||
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,17): error TS1187: A parameter property may not be declared using a binding pattern.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,27): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x1' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,31): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x2' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,35): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x3' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,27): error TS2459: Type 'ObjType1' has no property 'x1' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,31): error TS2459: Type 'ObjType1' has no property 'x2' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,35): error TS2459: Type 'ObjType1' has no property 'x3' and no string index signature.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,29): error TS2339: Property 'x1' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,40): error TS2339: Property 'x2' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,51): error TS2339: Property 'x3' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,62): error TS2339: Property 'y' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,72): error TS2339: Property 'z' does not exist on type 'C1'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,19): error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[{ x: number; y: string; z: boolean; }, number, string]'.
|
||||
Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'.
|
||||
Object literal may only specify known properties, and 'x1' does not exist in type '{ x: number; y: string; z: boolean; }'.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,19): error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[ObjType1, number, string]'.
|
||||
Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'.
|
||||
Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (10 errors) ====
|
||||
|
@ -21,11 +21,11 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1187: A parameter property may not be declared using a binding pattern.
|
||||
~~
|
||||
!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x1' and no string index signature.
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x1' and no string index signature.
|
||||
~~
|
||||
!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x2' and no string index signature.
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x2' and no string index signature.
|
||||
~~
|
||||
!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x3' and no string index signature.
|
||||
!!! error TS2459: Type 'ObjType1' has no property 'x3' and no string index signature.
|
||||
var foo: any = x1 || x2 || x3 || y || z;
|
||||
var bar: any = this.x1 || this.x2 || this.x3 || this.y || this.z;
|
||||
~~
|
||||
|
@ -43,7 +43,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1
|
|||
|
||||
var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]);
|
||||
~~~~~~
|
||||
!!! error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[{ x: number; y: string; z: boolean; }, number, string]'.
|
||||
!!! error TS2345: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'x1' does not exist in type '{ x: number; y: string; z: boolean; }'.
|
||||
!!! error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[ObjType1, number, string]'.
|
||||
!!! error TS2345: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'.
|
||||
var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z];
|
|
@ -1,6 +1,6 @@
|
|||
=== tests/cases/compiler/implicitIndexSignatures.ts ===
|
||||
type StringMap = { [x: string]: string };
|
||||
>StringMap : { [x: string]: string; }
|
||||
>StringMap : StringMap
|
||||
>x : string
|
||||
|
||||
const empty1 = {};
|
||||
|
@ -24,12 +24,12 @@ let names2: { a: string, b: string };
|
|||
>b : string
|
||||
|
||||
let map: StringMap;
|
||||
>map : { [x: string]: string; }
|
||||
>StringMap : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>StringMap : StringMap
|
||||
|
||||
map = { x: "xxx", y: "yyy" };
|
||||
>map = { x: "xxx", y: "yyy" } : { x: string; y: string; }
|
||||
>map : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>{ x: "xxx", y: "yyy" } : { x: string; y: string; }
|
||||
>x : string
|
||||
>"xxx" : "xxx"
|
||||
|
@ -38,22 +38,22 @@ map = { x: "xxx", y: "yyy" };
|
|||
|
||||
map = empty1;
|
||||
>map = empty1 : {}
|
||||
>map : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>empty1 : {}
|
||||
|
||||
map = empty2;
|
||||
>map = empty2 : {}
|
||||
>map : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>empty2 : {}
|
||||
|
||||
map = names1;
|
||||
>map = names1 : { a: string; b: string; }
|
||||
>map : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>names1 : { a: string; b: string; }
|
||||
|
||||
map = names2;
|
||||
>map = names2 : { a: string; b: string; }
|
||||
>map : { [x: string]: string; }
|
||||
>map : StringMap
|
||||
>names2 : { a: string; b: string; }
|
||||
|
||||
declare function getStringIndexValue<T>(map: { [x: string]: T }): T;
|
||||
|
|
|
@ -189,7 +189,7 @@ var z: Z4;
|
|||
// Repro from #9919
|
||||
|
||||
type ToString = {
|
||||
>ToString : { toString(): string; }
|
||||
>ToString : ToString
|
||||
|
||||
toString(): string;
|
||||
>toString : () => string
|
||||
|
@ -207,18 +207,18 @@ type BoxedValue = { kind: 'int', num: number }
|
|||
type IntersectionFail = BoxedValue & ToString
|
||||
>IntersectionFail : IntersectionFail
|
||||
>BoxedValue : BoxedValue
|
||||
>ToString : { toString(): string; }
|
||||
>ToString : ToString
|
||||
|
||||
type IntersectionInline = { kind: 'int', num: number } & ToString
|
||||
>IntersectionInline : IntersectionInline
|
||||
>kind : "int"
|
||||
>num : number
|
||||
>ToString : { toString(): string; }
|
||||
>ToString : ToString
|
||||
|
||||
| { kind: 'string', str: string } & ToString
|
||||
>kind : "string"
|
||||
>str : string
|
||||
>ToString : { toString(): string; }
|
||||
>ToString : ToString
|
||||
|
||||
function getValueAsString(value: IntersectionFail): string {
|
||||
>getValueAsString : (value: IntersectionFail) => string
|
||||
|
@ -236,11 +236,11 @@ function getValueAsString(value: IntersectionFail): string {
|
|||
>'' + value.num : string
|
||||
>'' : ""
|
||||
>value.num : number
|
||||
>value : { kind: "int"; num: number; } & { toString(): string; }
|
||||
>value : { kind: "int"; num: number; } & ToString
|
||||
>num : number
|
||||
}
|
||||
return value.str;
|
||||
>value.str : string
|
||||
>value : { kind: "string"; str: string; } & { toString(): string; }
|
||||
>value : { kind: "string"; str: string; } & ToString
|
||||
>str : string
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class Options {
|
|||
}
|
||||
|
||||
type Dictionary<T> = { [x: string]: T };
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>T : T
|
||||
>x : string
|
||||
>T : T
|
||||
|
@ -88,7 +88,7 @@ type K11 = keyof Shape[]; // number | "length" | "toString" | ...
|
|||
|
||||
type K12 = keyof Dictionary<Shape>; // string | number
|
||||
>K12 : string | number
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>Shape : Shape
|
||||
|
||||
type K13 = keyof {}; // never
|
||||
|
@ -128,7 +128,7 @@ type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
|
|||
type K21 = KeyOf<Dictionary<Shape>>; // string | number
|
||||
>K21 : string | number
|
||||
>KeyOf : keyof T
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>Shape : Shape
|
||||
|
||||
type NAME = "name";
|
||||
|
@ -201,17 +201,17 @@ type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false
|
|||
|
||||
type Q50 = Dictionary<Shape>["howdy"]; // Shape
|
||||
>Q50 : Shape
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>Shape : Shape
|
||||
|
||||
type Q51 = Dictionary<Shape>[123]; // Shape
|
||||
>Q51 : Shape
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>Shape : Shape
|
||||
|
||||
type Q52 = Dictionary<Shape>[E.B]; // Shape
|
||||
>Q52 : Shape
|
||||
>Dictionary : { [x: string]: T; }
|
||||
>Dictionary : Dictionary<T>
|
||||
>Shape : Shape
|
||||
>E : any
|
||||
>B : E.B
|
||||
|
|
110
tests/baselines/reference/mappedTypeErrors.errors.txt
Normal file
110
tests/baselines/reference/mappedTypeErrors.errors.txt
Normal file
|
@ -0,0 +1,110 @@
|
|||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(34,20): error TS2313: Type parameter 'P' has a circular constraint.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(35,20): error TS2322: Type 'Date' is not assignable to type 'string | number'.
|
||||
Type 'Date' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(36,19): error TS2344: Type 'Date' does not satisfy the constraint 'string | number'.
|
||||
Type 'Date' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(39,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(40,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
Type '"foo"' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(42,24): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
Type '"x"' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(44,24): error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(47,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
Type 'T' is not assignable to type '"visible"'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(51,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
Type 'string | number' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
Type 'string' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
Type 'T' is not assignable to type '"visible"'.
|
||||
Type 'string | number' is not assignable to type '"visible"'.
|
||||
Type 'string' is not assignable to type '"visible"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (9 errors) ====
|
||||
|
||||
type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
}
|
||||
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface Named {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
type T00 = { [P in P]: string }; // Error
|
||||
~
|
||||
!!! error TS2313: Type parameter 'P' has a circular constraint.
|
||||
type T01 = { [P in Date]: number }; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'Date' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type 'Date' is not assignable to type 'number'.
|
||||
type T02 = Record<Date, number>; // Error
|
||||
~~~~
|
||||
!!! error TS2344: Type 'Date' does not satisfy the constraint 'string | number'.
|
||||
!!! error TS2344: Type 'Date' is not assignable to type 'number'.
|
||||
|
||||
type T10 = Pick<Shape, "name">;
|
||||
type T11 = Pick<Shape, "foo">; // Error
|
||||
~~~~~
|
||||
!!! error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
type T12 = Pick<Shape, "name" | "foo">; // Error
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type '"foo"' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
type T13 = Pick<Shape, keyof Named>;
|
||||
type T14 = Pick<Shape, keyof Point>; // Error
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type '"x"' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
type T15 = Pick<Shape, never>;
|
||||
type T16 = Pick<Shape, undefined>; // Error
|
||||
~~~~~~~~~
|
||||
!!! error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
|
||||
function f1<T>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
~
|
||||
!!! error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type 'T' is not assignable to type '"visible"'.
|
||||
}
|
||||
|
||||
function f2<T extends string | number>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
~
|
||||
!!! error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type 'string | number' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type 'string' is not assignable to type '"name" | "width" | "height" | "visible"'.
|
||||
!!! error TS2344: Type 'T' is not assignable to type '"visible"'.
|
||||
!!! error TS2344: Type 'string | number' is not assignable to type '"visible"'.
|
||||
!!! error TS2344: Type 'string' is not assignable to type '"visible"'.
|
||||
}
|
||||
|
||||
function f3<T extends keyof Shape>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
||||
|
||||
function f4<T extends keyof Named>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
121
tests/baselines/reference/mappedTypeErrors.js
Normal file
121
tests/baselines/reference/mappedTypeErrors.js
Normal file
|
@ -0,0 +1,121 @@
|
|||
//// [mappedTypeErrors.ts]
|
||||
|
||||
type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
}
|
||||
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface Named {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
type T00 = { [P in P]: string }; // Error
|
||||
type T01 = { [P in Date]: number }; // Error
|
||||
type T02 = Record<Date, number>; // Error
|
||||
|
||||
type T10 = Pick<Shape, "name">;
|
||||
type T11 = Pick<Shape, "foo">; // Error
|
||||
type T12 = Pick<Shape, "name" | "foo">; // Error
|
||||
type T13 = Pick<Shape, keyof Named>;
|
||||
type T14 = Pick<Shape, keyof Point>; // Error
|
||||
type T15 = Pick<Shape, never>;
|
||||
type T16 = Pick<Shape, undefined>; // Error
|
||||
|
||||
function f1<T>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
}
|
||||
|
||||
function f2<T extends string | number>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
}
|
||||
|
||||
function f3<T extends keyof Shape>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
||||
|
||||
function f4<T extends keyof Named>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
||||
|
||||
//// [mappedTypeErrors.js]
|
||||
function f1(x) {
|
||||
var y; // Error
|
||||
}
|
||||
function f2(x) {
|
||||
var y; // Error
|
||||
}
|
||||
function f3(x) {
|
||||
var y;
|
||||
}
|
||||
function f4(x) {
|
||||
var y;
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeErrors.d.ts]
|
||||
declare type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
declare type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
declare type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
};
|
||||
declare type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
};
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
interface Named {
|
||||
name: string;
|
||||
}
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
declare type T00 = {
|
||||
[P in P]: string;
|
||||
};
|
||||
declare type T01 = {
|
||||
[P in Date]: number;
|
||||
};
|
||||
declare type T02 = Record<Date, number>;
|
||||
declare type T10 = Pick<Shape, "name">;
|
||||
declare type T11 = Pick<Shape, "foo">;
|
||||
declare type T12 = Pick<Shape, "name" | "foo">;
|
||||
declare type T13 = Pick<Shape, keyof Named>;
|
||||
declare type T14 = Pick<Shape, keyof Point>;
|
||||
declare type T15 = Pick<Shape, never>;
|
||||
declare type T16 = Pick<Shape, undefined>;
|
||||
declare function f1<T>(x: T): void;
|
||||
declare function f2<T extends string | number>(x: T): void;
|
||||
declare function f3<T extends keyof Shape>(x: T): void;
|
||||
declare function f4<T extends keyof Named>(x: T): void;
|
179
tests/baselines/reference/mappedTypes1.js
Normal file
179
tests/baselines/reference/mappedTypes1.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
//// [mappedTypes1.ts]
|
||||
|
||||
type Item = { a: string, b: number, c: boolean };
|
||||
|
||||
type T00 = { [P in "x" | "y"]: number };
|
||||
type T01 = { [P in "x" | "y"]: P };
|
||||
type T02 = { [P in "a" | "b"]: Item[P]; }
|
||||
type T03 = { [P in keyof Item]: Date };
|
||||
|
||||
type T10 = { [P in keyof Item]: Item[P] };
|
||||
type T11 = { [P in keyof Item]?: Item[P] };
|
||||
type T12 = { readonly [P in keyof Item]: Item[P] };
|
||||
type T13 = { readonly [P in keyof Item]?: Item[P] };
|
||||
|
||||
type T20 = { [P in keyof Item]: Item[P] | null };
|
||||
type T21 = { [P in keyof Item]: Array<Item[P]> };
|
||||
|
||||
type T30 = { [P in keyof any]: void };
|
||||
type T31 = { [P in keyof string]: void };
|
||||
type T32 = { [P in keyof number]: void };
|
||||
type T33 = { [P in keyof boolean]: void };
|
||||
type T34 = { [P in keyof undefined]: void };
|
||||
type T35 = { [P in keyof null]: void };
|
||||
type T36 = { [P in keyof void]: void };
|
||||
type T37 = { [P in keyof symbol]: void };
|
||||
type T38 = { [P in keyof never]: void };
|
||||
|
||||
type T40 = { [P in string]: void };
|
||||
type T41 = { [P in number]: void };
|
||||
type T42 = { [P in string | number]: void };
|
||||
type T43 = { [P in "a" | "b" | 0 | 1]: void };
|
||||
type T44 = { [P in "a" | "b" | "0" | "1"]: void };
|
||||
type T45 = { [P in "a" | "b" | "0" | "1" | 0 | 1]: void };
|
||||
type T46 = { [P in number | "a" | "b" | 0 | 1]: void };
|
||||
type T47 = { [P in string | number | "a" | "b" | 0 | 1]: void };
|
||||
|
||||
declare function f1<T1>(): { [P in keyof T1]: void };
|
||||
declare function f2<T1 extends string>(): { [P in keyof T1]: void };
|
||||
declare function f3<T1 extends number>(): { [P in keyof T1]: void };
|
||||
|
||||
let x1 = f1();
|
||||
let x2 = f2();
|
||||
let x3 = f3();
|
||||
|
||||
//// [mappedTypes1.js]
|
||||
var x1 = f1();
|
||||
var x2 = f2();
|
||||
var x3 = f3();
|
||||
|
||||
|
||||
//// [mappedTypes1.d.ts]
|
||||
declare type Item = {
|
||||
a: string;
|
||||
b: number;
|
||||
c: boolean;
|
||||
};
|
||||
declare type T00 = {
|
||||
[P in "x" | "y"]: number;
|
||||
};
|
||||
declare type T01 = {
|
||||
[P in "x" | "y"]: P;
|
||||
};
|
||||
declare type T02 = {
|
||||
[P in "a" | "b"]: Item[P];
|
||||
};
|
||||
declare type T03 = {
|
||||
[P in keyof Item]: Date;
|
||||
};
|
||||
declare type T10 = {
|
||||
[P in keyof Item]: Item[P];
|
||||
};
|
||||
declare type T11 = {
|
||||
[P in keyof Item]?: Item[P];
|
||||
};
|
||||
declare type T12 = {
|
||||
readonly [P in keyof Item]: Item[P];
|
||||
};
|
||||
declare type T13 = {
|
||||
readonly [P in keyof Item]?: Item[P];
|
||||
};
|
||||
declare type T20 = {
|
||||
[P in keyof Item]: Item[P] | null;
|
||||
};
|
||||
declare type T21 = {
|
||||
[P in keyof Item]: Array<Item[P]>;
|
||||
};
|
||||
declare type T30 = {
|
||||
[P in keyof any]: void;
|
||||
};
|
||||
declare type T31 = {
|
||||
[P in keyof string]: void;
|
||||
};
|
||||
declare type T32 = {
|
||||
[P in keyof number]: void;
|
||||
};
|
||||
declare type T33 = {
|
||||
[P in keyof boolean]: void;
|
||||
};
|
||||
declare type T34 = {
|
||||
[P in keyof undefined]: void;
|
||||
};
|
||||
declare type T35 = {
|
||||
[P in keyof null]: void;
|
||||
};
|
||||
declare type T36 = {
|
||||
[P in keyof void]: void;
|
||||
};
|
||||
declare type T37 = {
|
||||
[P in keyof symbol]: void;
|
||||
};
|
||||
declare type T38 = {
|
||||
[P in keyof never]: void;
|
||||
};
|
||||
declare type T40 = {
|
||||
[P in string]: void;
|
||||
};
|
||||
declare type T41 = {
|
||||
[P in number]: void;
|
||||
};
|
||||
declare type T42 = {
|
||||
[P in string | number]: void;
|
||||
};
|
||||
declare type T43 = {
|
||||
[P in "a" | "b" | 0 | 1]: void;
|
||||
};
|
||||
declare type T44 = {
|
||||
[P in "a" | "b" | "0" | "1"]: void;
|
||||
};
|
||||
declare type T45 = {
|
||||
[P in "a" | "b" | "0" | "1" | 0 | 1]: void;
|
||||
};
|
||||
declare type T46 = {
|
||||
[P in number | "a" | "b" | 0 | 1]: void;
|
||||
};
|
||||
declare type T47 = {
|
||||
[P in string | number | "a" | "b" | 0 | 1]: void;
|
||||
};
|
||||
declare function f1<T1>(): {
|
||||
[P in keyof T1]: void;
|
||||
};
|
||||
declare function f2<T1 extends string>(): {
|
||||
[P in keyof T1]: void;
|
||||
};
|
||||
declare function f3<T1 extends number>(): {
|
||||
[P in keyof T1]: void;
|
||||
};
|
||||
declare let x1: {};
|
||||
declare let x2: {
|
||||
[x: number]: void;
|
||||
toString: void;
|
||||
charAt: void;
|
||||
charCodeAt: void;
|
||||
concat: void;
|
||||
indexOf: void;
|
||||
lastIndexOf: void;
|
||||
localeCompare: void;
|
||||
match: void;
|
||||
replace: void;
|
||||
search: void;
|
||||
slice: void;
|
||||
split: void;
|
||||
substring: void;
|
||||
toLowerCase: void;
|
||||
toLocaleLowerCase: void;
|
||||
toUpperCase: void;
|
||||
toLocaleUpperCase: void;
|
||||
trim: void;
|
||||
length: void;
|
||||
substr: void;
|
||||
valueOf: void;
|
||||
};
|
||||
declare let x3: {
|
||||
toString: void;
|
||||
valueOf: void;
|
||||
toFixed: void;
|
||||
toExponential: void;
|
||||
toPrecision: void;
|
||||
toLocaleString: void;
|
||||
};
|
170
tests/baselines/reference/mappedTypes1.symbols
Normal file
170
tests/baselines/reference/mappedTypes1.symbols
Normal file
|
@ -0,0 +1,170 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes1.ts ===
|
||||
|
||||
type Item = { a: string, b: number, c: boolean };
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(mappedTypes1.ts, 1, 13))
|
||||
>b : Symbol(b, Decl(mappedTypes1.ts, 1, 24))
|
||||
>c : Symbol(c, Decl(mappedTypes1.ts, 1, 35))
|
||||
|
||||
type T00 = { [P in "x" | "y"]: number };
|
||||
>T00 : Symbol(T00, Decl(mappedTypes1.ts, 1, 49))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 3, 14))
|
||||
|
||||
type T01 = { [P in "x" | "y"]: P };
|
||||
>T01 : Symbol(T01, Decl(mappedTypes1.ts, 3, 40))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 4, 14))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 4, 14))
|
||||
|
||||
type T02 = { [P in "a" | "b"]: Item[P]; }
|
||||
>T02 : Symbol(T02, Decl(mappedTypes1.ts, 4, 35))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 5, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 5, 14))
|
||||
|
||||
type T03 = { [P in keyof Item]: Date };
|
||||
>T03 : Symbol(T03, Decl(mappedTypes1.ts, 5, 41))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 6, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
type T10 = { [P in keyof Item]: Item[P] };
|
||||
>T10 : Symbol(T10, Decl(mappedTypes1.ts, 6, 39))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 8, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 8, 14))
|
||||
|
||||
type T11 = { [P in keyof Item]?: Item[P] };
|
||||
>T11 : Symbol(T11, Decl(mappedTypes1.ts, 8, 42))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 9, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 9, 14))
|
||||
|
||||
type T12 = { readonly [P in keyof Item]: Item[P] };
|
||||
>T12 : Symbol(T12, Decl(mappedTypes1.ts, 9, 43))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 10, 23))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 10, 23))
|
||||
|
||||
type T13 = { readonly [P in keyof Item]?: Item[P] };
|
||||
>T13 : Symbol(T13, Decl(mappedTypes1.ts, 10, 51))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 11, 23))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 11, 23))
|
||||
|
||||
type T20 = { [P in keyof Item]: Item[P] | null };
|
||||
>T20 : Symbol(T20, Decl(mappedTypes1.ts, 11, 52))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 13, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 13, 14))
|
||||
|
||||
type T21 = { [P in keyof Item]: Array<Item[P]> };
|
||||
>T21 : Symbol(T21, Decl(mappedTypes1.ts, 13, 49))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 14, 14))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>Item : Symbol(Item, Decl(mappedTypes1.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 14, 14))
|
||||
|
||||
type T30 = { [P in keyof any]: void };
|
||||
>T30 : Symbol(T30, Decl(mappedTypes1.ts, 14, 49))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 16, 14))
|
||||
|
||||
type T31 = { [P in keyof string]: void };
|
||||
>T31 : Symbol(T31, Decl(mappedTypes1.ts, 16, 38))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 17, 14))
|
||||
|
||||
type T32 = { [P in keyof number]: void };
|
||||
>T32 : Symbol(T32, Decl(mappedTypes1.ts, 17, 41))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 18, 14))
|
||||
|
||||
type T33 = { [P in keyof boolean]: void };
|
||||
>T33 : Symbol(T33, Decl(mappedTypes1.ts, 18, 41))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 19, 14))
|
||||
|
||||
type T34 = { [P in keyof undefined]: void };
|
||||
>T34 : Symbol(T34, Decl(mappedTypes1.ts, 19, 42))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 20, 14))
|
||||
|
||||
type T35 = { [P in keyof null]: void };
|
||||
>T35 : Symbol(T35, Decl(mappedTypes1.ts, 20, 44))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 21, 14))
|
||||
|
||||
type T36 = { [P in keyof void]: void };
|
||||
>T36 : Symbol(T36, Decl(mappedTypes1.ts, 21, 39))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 22, 14))
|
||||
|
||||
type T37 = { [P in keyof symbol]: void };
|
||||
>T37 : Symbol(T37, Decl(mappedTypes1.ts, 22, 39))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 23, 14))
|
||||
|
||||
type T38 = { [P in keyof never]: void };
|
||||
>T38 : Symbol(T38, Decl(mappedTypes1.ts, 23, 41))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 24, 14))
|
||||
|
||||
type T40 = { [P in string]: void };
|
||||
>T40 : Symbol(T40, Decl(mappedTypes1.ts, 24, 40))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 26, 14))
|
||||
|
||||
type T41 = { [P in number]: void };
|
||||
>T41 : Symbol(T41, Decl(mappedTypes1.ts, 26, 35))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 27, 14))
|
||||
|
||||
type T42 = { [P in string | number]: void };
|
||||
>T42 : Symbol(T42, Decl(mappedTypes1.ts, 27, 35))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 28, 14))
|
||||
|
||||
type T43 = { [P in "a" | "b" | 0 | 1]: void };
|
||||
>T43 : Symbol(T43, Decl(mappedTypes1.ts, 28, 44))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 29, 14))
|
||||
|
||||
type T44 = { [P in "a" | "b" | "0" | "1"]: void };
|
||||
>T44 : Symbol(T44, Decl(mappedTypes1.ts, 29, 46))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 30, 14))
|
||||
|
||||
type T45 = { [P in "a" | "b" | "0" | "1" | 0 | 1]: void };
|
||||
>T45 : Symbol(T45, Decl(mappedTypes1.ts, 30, 50))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 31, 14))
|
||||
|
||||
type T46 = { [P in number | "a" | "b" | 0 | 1]: void };
|
||||
>T46 : Symbol(T46, Decl(mappedTypes1.ts, 31, 58))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 32, 14))
|
||||
|
||||
type T47 = { [P in string | number | "a" | "b" | 0 | 1]: void };
|
||||
>T47 : Symbol(T47, Decl(mappedTypes1.ts, 32, 55))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 33, 14))
|
||||
|
||||
declare function f1<T1>(): { [P in keyof T1]: void };
|
||||
>f1 : Symbol(f1, Decl(mappedTypes1.ts, 33, 64))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 35, 20))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 35, 30))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 35, 20))
|
||||
|
||||
declare function f2<T1 extends string>(): { [P in keyof T1]: void };
|
||||
>f2 : Symbol(f2, Decl(mappedTypes1.ts, 35, 53))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 36, 20))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 36, 45))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 36, 20))
|
||||
|
||||
declare function f3<T1 extends number>(): { [P in keyof T1]: void };
|
||||
>f3 : Symbol(f3, Decl(mappedTypes1.ts, 36, 68))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 37, 20))
|
||||
>P : Symbol(P, Decl(mappedTypes1.ts, 37, 45))
|
||||
>T1 : Symbol(T1, Decl(mappedTypes1.ts, 37, 20))
|
||||
|
||||
let x1 = f1();
|
||||
>x1 : Symbol(x1, Decl(mappedTypes1.ts, 39, 3))
|
||||
>f1 : Symbol(f1, Decl(mappedTypes1.ts, 33, 64))
|
||||
|
||||
let x2 = f2();
|
||||
>x2 : Symbol(x2, Decl(mappedTypes1.ts, 40, 3))
|
||||
>f2 : Symbol(f2, Decl(mappedTypes1.ts, 35, 53))
|
||||
|
||||
let x3 = f3();
|
||||
>x3 : Symbol(x3, Decl(mappedTypes1.ts, 41, 3))
|
||||
>f3 : Symbol(f3, Decl(mappedTypes1.ts, 36, 68))
|
||||
|
175
tests/baselines/reference/mappedTypes1.types
Normal file
175
tests/baselines/reference/mappedTypes1.types
Normal file
|
@ -0,0 +1,175 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes1.ts ===
|
||||
|
||||
type Item = { a: string, b: number, c: boolean };
|
||||
>Item : Item
|
||||
>a : string
|
||||
>b : number
|
||||
>c : boolean
|
||||
|
||||
type T00 = { [P in "x" | "y"]: number };
|
||||
>T00 : T00
|
||||
>P : P
|
||||
|
||||
type T01 = { [P in "x" | "y"]: P };
|
||||
>T01 : T01
|
||||
>P : P
|
||||
>P : P
|
||||
|
||||
type T02 = { [P in "a" | "b"]: Item[P]; }
|
||||
>T02 : T02
|
||||
>P : P
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T03 = { [P in keyof Item]: Date };
|
||||
>T03 : T03
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Date : Date
|
||||
|
||||
type T10 = { [P in keyof Item]: Item[P] };
|
||||
>T10 : T10
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T11 = { [P in keyof Item]?: Item[P] };
|
||||
>T11 : T11
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T12 = { readonly [P in keyof Item]: Item[P] };
|
||||
>T12 : T12
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T13 = { readonly [P in keyof Item]?: Item[P] };
|
||||
>T13 : T13
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T20 = { [P in keyof Item]: Item[P] | null };
|
||||
>T20 : T20
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Item : Item
|
||||
>P : P
|
||||
>null : null
|
||||
|
||||
type T21 = { [P in keyof Item]: Array<Item[P]> };
|
||||
>T21 : T21
|
||||
>P : P
|
||||
>Item : Item
|
||||
>Array : T[]
|
||||
>Item : Item
|
||||
>P : P
|
||||
|
||||
type T30 = { [P in keyof any]: void };
|
||||
>T30 : T30
|
||||
>P : P
|
||||
|
||||
type T31 = { [P in keyof string]: void };
|
||||
>T31 : T31
|
||||
>P : P
|
||||
|
||||
type T32 = { [P in keyof number]: void };
|
||||
>T32 : T32
|
||||
>P : P
|
||||
|
||||
type T33 = { [P in keyof boolean]: void };
|
||||
>T33 : T33
|
||||
>P : P
|
||||
|
||||
type T34 = { [P in keyof undefined]: void };
|
||||
>T34 : T34
|
||||
>P : P
|
||||
|
||||
type T35 = { [P in keyof null]: void };
|
||||
>T35 : T35
|
||||
>P : P
|
||||
>null : null
|
||||
|
||||
type T36 = { [P in keyof void]: void };
|
||||
>T36 : T36
|
||||
>P : P
|
||||
|
||||
type T37 = { [P in keyof symbol]: void };
|
||||
>T37 : T37
|
||||
>P : P
|
||||
|
||||
type T38 = { [P in keyof never]: void };
|
||||
>T38 : T38
|
||||
>P : P
|
||||
|
||||
type T40 = { [P in string]: void };
|
||||
>T40 : T40
|
||||
>P : P
|
||||
|
||||
type T41 = { [P in number]: void };
|
||||
>T41 : T41
|
||||
>P : P
|
||||
|
||||
type T42 = { [P in string | number]: void };
|
||||
>T42 : T42
|
||||
>P : P
|
||||
|
||||
type T43 = { [P in "a" | "b" | 0 | 1]: void };
|
||||
>T43 : T43
|
||||
>P : P
|
||||
|
||||
type T44 = { [P in "a" | "b" | "0" | "1"]: void };
|
||||
>T44 : T44
|
||||
>P : P
|
||||
|
||||
type T45 = { [P in "a" | "b" | "0" | "1" | 0 | 1]: void };
|
||||
>T45 : T45
|
||||
>P : P
|
||||
|
||||
type T46 = { [P in number | "a" | "b" | 0 | 1]: void };
|
||||
>T46 : T46
|
||||
>P : P
|
||||
|
||||
type T47 = { [P in string | number | "a" | "b" | 0 | 1]: void };
|
||||
>T47 : T47
|
||||
>P : P
|
||||
|
||||
declare function f1<T1>(): { [P in keyof T1]: void };
|
||||
>f1 : <T1>() => { [P in keyof T1]: void; }
|
||||
>T1 : T1
|
||||
>P : P
|
||||
>T1 : T1
|
||||
|
||||
declare function f2<T1 extends string>(): { [P in keyof T1]: void };
|
||||
>f2 : <T1 extends string>() => { [P in keyof T1]: void; }
|
||||
>T1 : T1
|
||||
>P : P
|
||||
>T1 : T1
|
||||
|
||||
declare function f3<T1 extends number>(): { [P in keyof T1]: void };
|
||||
>f3 : <T1 extends number>() => { [P in keyof T1]: void; }
|
||||
>T1 : T1
|
||||
>P : P
|
||||
>T1 : T1
|
||||
|
||||
let x1 = f1();
|
||||
>x1 : {}
|
||||
>f1() : {}
|
||||
>f1 : <T1>() => { [P in keyof T1]: void; }
|
||||
|
||||
let x2 = f2();
|
||||
>x2 : { [x: number]: void; toString: void; charAt: void; charCodeAt: void; concat: void; indexOf: void; lastIndexOf: void; localeCompare: void; match: void; replace: void; search: void; slice: void; split: void; substring: void; toLowerCase: void; toLocaleLowerCase: void; toUpperCase: void; toLocaleUpperCase: void; trim: void; length: void; substr: void; valueOf: void; }
|
||||
>f2() : { [x: number]: void; toString: void; charAt: void; charCodeAt: void; concat: void; indexOf: void; lastIndexOf: void; localeCompare: void; match: void; replace: void; search: void; slice: void; split: void; substring: void; toLowerCase: void; toLocaleLowerCase: void; toUpperCase: void; toLocaleUpperCase: void; trim: void; length: void; substr: void; valueOf: void; }
|
||||
>f2 : <T1 extends string>() => { [P in keyof T1]: void; }
|
||||
|
||||
let x3 = f3();
|
||||
>x3 : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; }
|
||||
>f3() : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; }
|
||||
>f3 : <T1 extends number>() => { [P in keyof T1]: void; }
|
||||
|
183
tests/baselines/reference/mappedTypes2.js
Normal file
183
tests/baselines/reference/mappedTypes2.js
Normal file
|
@ -0,0 +1,183 @@
|
|||
//// [mappedTypes2.ts]
|
||||
|
||||
type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
}
|
||||
|
||||
type Proxy<T> = {
|
||||
get(): T;
|
||||
set(value: T): void;
|
||||
}
|
||||
|
||||
type Proxify<T> = {
|
||||
[P in keyof T]: Proxy<T[P]>;
|
||||
}
|
||||
|
||||
type DeepReadonly<T> = {
|
||||
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
||||
};
|
||||
|
||||
declare function assign<T>(obj: T, props: Partial<T>): void;
|
||||
declare function freeze<T>(obj: T): Readonly<T>;
|
||||
declare function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;
|
||||
declare function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>;
|
||||
declare function proxify<T>(obj: T): Proxify<T>;
|
||||
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface PartialShape {
|
||||
name?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
interface ReadonlyShape {
|
||||
readonly name: string;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly visible: boolean;
|
||||
}
|
||||
|
||||
function f0(s1: Shape, s2: Shape) {
|
||||
assign(s1, { name: "circle" });
|
||||
assign(s2, { width: 10, height: 20 });
|
||||
}
|
||||
|
||||
function f1(shape: Shape) {
|
||||
var frozen: ReadonlyShape;
|
||||
var frozen: Readonly<Shape>;
|
||||
var frozen = freeze(shape);
|
||||
}
|
||||
|
||||
function f2(shape: Shape) {
|
||||
var partial: PartialShape;
|
||||
var partial: Partial<Shape>;
|
||||
var partial: Partial<Shape> = {};
|
||||
}
|
||||
|
||||
function f3(shape: Shape) {
|
||||
const x = pick(shape, "name", "visible"); // { name: string, visible: boolean }
|
||||
}
|
||||
|
||||
function f4() {
|
||||
const rec = { foo: "hello", bar: "world", baz: "bye" };
|
||||
const lengths = mapObject(rec, s => s.length); // { foo: number, bar: number, baz: number }
|
||||
}
|
||||
|
||||
function f5(shape: Shape) {
|
||||
const p = proxify(shape);
|
||||
let name = p.name.get();
|
||||
p.visible.set(false);
|
||||
}
|
||||
|
||||
function f6(shape: DeepReadonly<Shape>) {
|
||||
let name = shape.name; // DeepReadonly<string>
|
||||
let length = name.length; // DeepReadonly<number>
|
||||
let toString = length.toString; // DeepReadonly<(radix?: number) => string>
|
||||
}
|
||||
|
||||
//// [mappedTypes2.js]
|
||||
function f0(s1, s2) {
|
||||
assign(s1, { name: "circle" });
|
||||
assign(s2, { width: 10, height: 20 });
|
||||
}
|
||||
function f1(shape) {
|
||||
var frozen;
|
||||
var frozen;
|
||||
var frozen = freeze(shape);
|
||||
}
|
||||
function f2(shape) {
|
||||
var partial;
|
||||
var partial;
|
||||
var partial = {};
|
||||
}
|
||||
function f3(shape) {
|
||||
var x = pick(shape, "name", "visible"); // { name: string, visible: boolean }
|
||||
}
|
||||
function f4() {
|
||||
var rec = { foo: "hello", bar: "world", baz: "bye" };
|
||||
var lengths = mapObject(rec, function (s) { return s.length; }); // { foo: number, bar: number, baz: number }
|
||||
}
|
||||
function f5(shape) {
|
||||
var p = proxify(shape);
|
||||
var name = p.name.get();
|
||||
p.visible.set(false);
|
||||
}
|
||||
function f6(shape) {
|
||||
var name = shape.name; // DeepReadonly<string>
|
||||
var length = name.length; // DeepReadonly<number>
|
||||
var toString = length.toString; // DeepReadonly<(radix?: number) => string>
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypes2.d.ts]
|
||||
declare type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
declare type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
declare type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
};
|
||||
declare type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
};
|
||||
declare type Proxy<T> = {
|
||||
get(): T;
|
||||
set(value: T): void;
|
||||
};
|
||||
declare type Proxify<T> = {
|
||||
[P in keyof T]: Proxy<T[P]>;
|
||||
};
|
||||
declare type DeepReadonly<T> = {
|
||||
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
||||
};
|
||||
declare function assign<T>(obj: T, props: Partial<T>): void;
|
||||
declare function freeze<T>(obj: T): Readonly<T>;
|
||||
declare function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;
|
||||
declare function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>;
|
||||
declare function proxify<T>(obj: T): Proxify<T>;
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
interface PartialShape {
|
||||
name?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
visible?: boolean;
|
||||
}
|
||||
interface ReadonlyShape {
|
||||
readonly name: string;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly visible: boolean;
|
||||
}
|
||||
declare function f0(s1: Shape, s2: Shape): void;
|
||||
declare function f1(shape: Shape): void;
|
||||
declare function f2(shape: Shape): void;
|
||||
declare function f3(shape: Shape): void;
|
||||
declare function f4(): void;
|
||||
declare function f5(shape: Shape): void;
|
||||
declare function f6(shape: DeepReadonly<Shape>): void;
|
331
tests/baselines/reference/mappedTypes2.symbols
Normal file
331
tests/baselines/reference/mappedTypes2.symbols
Normal file
|
@ -0,0 +1,331 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes2.ts ===
|
||||
|
||||
type Partial<T> = {
|
||||
>Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 1, 13))
|
||||
|
||||
[P in keyof T]?: T[P];
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 2, 5))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 1, 13))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 1, 13))
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 2, 5))
|
||||
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
>Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 5, 14))
|
||||
|
||||
readonly [P in keyof T]: T[P];
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 6, 14))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 5, 14))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 5, 14))
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 6, 14))
|
||||
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
>Pick : Symbol(Pick, Decl(mappedTypes2.ts, 7, 2))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 9, 10))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 9, 12))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 9, 10))
|
||||
|
||||
[P in K]: T[P];
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 10, 5))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 9, 12))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 9, 10))
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 10, 5))
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
>Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 13, 12))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 13, 38))
|
||||
|
||||
[_ in K]: T;
|
||||
>_ : Symbol(_, Decl(mappedTypes2.ts, 14, 5))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 13, 12))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 13, 38))
|
||||
}
|
||||
|
||||
type Proxy<T> = {
|
||||
>Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 15, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 17, 11))
|
||||
|
||||
get(): T;
|
||||
>get : Symbol(get, Decl(mappedTypes2.ts, 17, 17))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 17, 11))
|
||||
|
||||
set(value: T): void;
|
||||
>set : Symbol(set, Decl(mappedTypes2.ts, 18, 13))
|
||||
>value : Symbol(value, Decl(mappedTypes2.ts, 19, 8))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 17, 11))
|
||||
}
|
||||
|
||||
type Proxify<T> = {
|
||||
>Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 20, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 22, 13))
|
||||
|
||||
[P in keyof T]: Proxy<T[P]>;
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 23, 5))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 22, 13))
|
||||
>Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 15, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 22, 13))
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 23, 5))
|
||||
}
|
||||
|
||||
type DeepReadonly<T> = {
|
||||
>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 26, 18))
|
||||
|
||||
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 27, 14))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 26, 18))
|
||||
>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 26, 18))
|
||||
>P : Symbol(P, Decl(mappedTypes2.ts, 27, 14))
|
||||
|
||||
};
|
||||
|
||||
declare function assign<T>(obj: T, props: Partial<T>): void;
|
||||
>assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 30, 24))
|
||||
>obj : Symbol(obj, Decl(mappedTypes2.ts, 30, 27))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 30, 24))
|
||||
>props : Symbol(props, Decl(mappedTypes2.ts, 30, 34))
|
||||
>Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 30, 24))
|
||||
|
||||
declare function freeze<T>(obj: T): Readonly<T>;
|
||||
>freeze : Symbol(freeze, Decl(mappedTypes2.ts, 30, 60))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 31, 24))
|
||||
>obj : Symbol(obj, Decl(mappedTypes2.ts, 31, 27))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 31, 24))
|
||||
>Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 31, 24))
|
||||
|
||||
declare function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;
|
||||
>pick : Symbol(pick, Decl(mappedTypes2.ts, 31, 48))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 32, 22))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 32, 24))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 32, 22))
|
||||
>obj : Symbol(obj, Decl(mappedTypes2.ts, 32, 44))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 32, 22))
|
||||
>keys : Symbol(keys, Decl(mappedTypes2.ts, 32, 51))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 32, 24))
|
||||
>Pick : Symbol(Pick, Decl(mappedTypes2.ts, 7, 2))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 32, 22))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 32, 24))
|
||||
|
||||
declare function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>;
|
||||
>mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 32, 78))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 33, 27))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 33, 53))
|
||||
>U : Symbol(U, Decl(mappedTypes2.ts, 33, 56))
|
||||
>obj : Symbol(obj, Decl(mappedTypes2.ts, 33, 60))
|
||||
>Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 33, 27))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 33, 53))
|
||||
>f : Symbol(f, Decl(mappedTypes2.ts, 33, 78))
|
||||
>x : Symbol(x, Decl(mappedTypes2.ts, 33, 83))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 33, 53))
|
||||
>U : Symbol(U, Decl(mappedTypes2.ts, 33, 56))
|
||||
>Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1))
|
||||
>K : Symbol(K, Decl(mappedTypes2.ts, 33, 27))
|
||||
>U : Symbol(U, Decl(mappedTypes2.ts, 33, 56))
|
||||
|
||||
declare function proxify<T>(obj: T): Proxify<T>;
|
||||
>proxify : Symbol(proxify, Decl(mappedTypes2.ts, 33, 109))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 34, 25))
|
||||
>obj : Symbol(obj, Decl(mappedTypes2.ts, 34, 28))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 34, 25))
|
||||
>Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 20, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes2.ts, 34, 25))
|
||||
|
||||
interface Shape {
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
name: string;
|
||||
>name : Symbol(Shape.name, Decl(mappedTypes2.ts, 36, 17))
|
||||
|
||||
width: number;
|
||||
>width : Symbol(Shape.width, Decl(mappedTypes2.ts, 37, 17))
|
||||
|
||||
height: number;
|
||||
>height : Symbol(Shape.height, Decl(mappedTypes2.ts, 38, 18))
|
||||
|
||||
visible: boolean;
|
||||
>visible : Symbol(Shape.visible, Decl(mappedTypes2.ts, 39, 19))
|
||||
}
|
||||
|
||||
interface PartialShape {
|
||||
>PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 41, 1))
|
||||
|
||||
name?: string;
|
||||
>name : Symbol(PartialShape.name, Decl(mappedTypes2.ts, 43, 24))
|
||||
|
||||
width?: number;
|
||||
>width : Symbol(PartialShape.width, Decl(mappedTypes2.ts, 44, 18))
|
||||
|
||||
height?: number;
|
||||
>height : Symbol(PartialShape.height, Decl(mappedTypes2.ts, 45, 19))
|
||||
|
||||
visible?: boolean;
|
||||
>visible : Symbol(PartialShape.visible, Decl(mappedTypes2.ts, 46, 20))
|
||||
}
|
||||
|
||||
interface ReadonlyShape {
|
||||
>ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 48, 1))
|
||||
|
||||
readonly name: string;
|
||||
>name : Symbol(ReadonlyShape.name, Decl(mappedTypes2.ts, 50, 25))
|
||||
|
||||
readonly width: number;
|
||||
>width : Symbol(ReadonlyShape.width, Decl(mappedTypes2.ts, 51, 26))
|
||||
|
||||
readonly height: number;
|
||||
>height : Symbol(ReadonlyShape.height, Decl(mappedTypes2.ts, 52, 27))
|
||||
|
||||
readonly visible: boolean;
|
||||
>visible : Symbol(ReadonlyShape.visible, Decl(mappedTypes2.ts, 53, 28))
|
||||
}
|
||||
|
||||
function f0(s1: Shape, s2: Shape) {
|
||||
>f0 : Symbol(f0, Decl(mappedTypes2.ts, 55, 1))
|
||||
>s1 : Symbol(s1, Decl(mappedTypes2.ts, 57, 12))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
>s2 : Symbol(s2, Decl(mappedTypes2.ts, 57, 22))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
assign(s1, { name: "circle" });
|
||||
>assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2))
|
||||
>s1 : Symbol(s1, Decl(mappedTypes2.ts, 57, 12))
|
||||
>name : Symbol(name, Decl(mappedTypes2.ts, 58, 16))
|
||||
|
||||
assign(s2, { width: 10, height: 20 });
|
||||
>assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2))
|
||||
>s2 : Symbol(s2, Decl(mappedTypes2.ts, 57, 22))
|
||||
>width : Symbol(width, Decl(mappedTypes2.ts, 59, 16))
|
||||
>height : Symbol(height, Decl(mappedTypes2.ts, 59, 27))
|
||||
}
|
||||
|
||||
function f1(shape: Shape) {
|
||||
>f1 : Symbol(f1, Decl(mappedTypes2.ts, 60, 1))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 62, 12))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
var frozen: ReadonlyShape;
|
||||
>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7))
|
||||
>ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 48, 1))
|
||||
|
||||
var frozen: Readonly<Shape>;
|
||||
>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7))
|
||||
>Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
var frozen = freeze(shape);
|
||||
>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7))
|
||||
>freeze : Symbol(freeze, Decl(mappedTypes2.ts, 30, 60))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 62, 12))
|
||||
}
|
||||
|
||||
function f2(shape: Shape) {
|
||||
>f2 : Symbol(f2, Decl(mappedTypes2.ts, 66, 1))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 68, 12))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
var partial: PartialShape;
|
||||
>partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7))
|
||||
>PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 41, 1))
|
||||
|
||||
var partial: Partial<Shape>;
|
||||
>partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7))
|
||||
>Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
var partial: Partial<Shape> = {};
|
||||
>partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7))
|
||||
>Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
}
|
||||
|
||||
function f3(shape: Shape) {
|
||||
>f3 : Symbol(f3, Decl(mappedTypes2.ts, 72, 1))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 74, 12))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
const x = pick(shape, "name", "visible"); // { name: string, visible: boolean }
|
||||
>x : Symbol(x, Decl(mappedTypes2.ts, 75, 9))
|
||||
>pick : Symbol(pick, Decl(mappedTypes2.ts, 31, 48))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 74, 12))
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : Symbol(f4, Decl(mappedTypes2.ts, 76, 1))
|
||||
|
||||
const rec = { foo: "hello", bar: "world", baz: "bye" };
|
||||
>rec : Symbol(rec, Decl(mappedTypes2.ts, 79, 9))
|
||||
>foo : Symbol(foo, Decl(mappedTypes2.ts, 79, 17))
|
||||
>bar : Symbol(bar, Decl(mappedTypes2.ts, 79, 31))
|
||||
>baz : Symbol(baz, Decl(mappedTypes2.ts, 79, 45))
|
||||
|
||||
const lengths = mapObject(rec, s => s.length); // { foo: number, bar: number, baz: number }
|
||||
>lengths : Symbol(lengths, Decl(mappedTypes2.ts, 80, 9))
|
||||
>mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 32, 78))
|
||||
>rec : Symbol(rec, Decl(mappedTypes2.ts, 79, 9))
|
||||
>s : Symbol(s, Decl(mappedTypes2.ts, 80, 34))
|
||||
>s.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>s : Symbol(s, Decl(mappedTypes2.ts, 80, 34))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function f5(shape: Shape) {
|
||||
>f5 : Symbol(f5, Decl(mappedTypes2.ts, 81, 1))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 83, 12))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
const p = proxify(shape);
|
||||
>p : Symbol(p, Decl(mappedTypes2.ts, 84, 9))
|
||||
>proxify : Symbol(proxify, Decl(mappedTypes2.ts, 33, 109))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 83, 12))
|
||||
|
||||
let name = p.name.get();
|
||||
>name : Symbol(name, Decl(mappedTypes2.ts, 85, 7))
|
||||
>p.name.get : Symbol(get, Decl(mappedTypes2.ts, 17, 17))
|
||||
>p.name : Symbol(name)
|
||||
>p : Symbol(p, Decl(mappedTypes2.ts, 84, 9))
|
||||
>name : Symbol(name)
|
||||
>get : Symbol(get, Decl(mappedTypes2.ts, 17, 17))
|
||||
|
||||
p.visible.set(false);
|
||||
>p.visible.set : Symbol(set, Decl(mappedTypes2.ts, 18, 13))
|
||||
>p.visible : Symbol(visible)
|
||||
>p : Symbol(p, Decl(mappedTypes2.ts, 84, 9))
|
||||
>visible : Symbol(visible)
|
||||
>set : Symbol(set, Decl(mappedTypes2.ts, 18, 13))
|
||||
}
|
||||
|
||||
function f6(shape: DeepReadonly<Shape>) {
|
||||
>f6 : Symbol(f6, Decl(mappedTypes2.ts, 87, 1))
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 89, 12))
|
||||
>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1))
|
||||
>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48))
|
||||
|
||||
let name = shape.name; // DeepReadonly<string>
|
||||
>name : Symbol(name, Decl(mappedTypes2.ts, 90, 7))
|
||||
>shape.name : Symbol(name)
|
||||
>shape : Symbol(shape, Decl(mappedTypes2.ts, 89, 12))
|
||||
>name : Symbol(name)
|
||||
|
||||
let length = name.length; // DeepReadonly<number>
|
||||
>length : Symbol(length, Decl(mappedTypes2.ts, 91, 7))
|
||||
>name.length : Symbol(length)
|
||||
>name : Symbol(name, Decl(mappedTypes2.ts, 90, 7))
|
||||
>length : Symbol(length)
|
||||
|
||||
let toString = length.toString; // DeepReadonly<(radix?: number) => string>
|
||||
>toString : Symbol(toString, Decl(mappedTypes2.ts, 92, 7))
|
||||
>length.toString : Symbol(toString)
|
||||
>length : Symbol(length, Decl(mappedTypes2.ts, 91, 7))
|
||||
>toString : Symbol(toString)
|
||||
}
|
353
tests/baselines/reference/mappedTypes2.types
Normal file
353
tests/baselines/reference/mappedTypes2.types
Normal file
|
@ -0,0 +1,353 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes2.ts ===
|
||||
|
||||
type Partial<T> = {
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
|
||||
[P in keyof T]?: T[P];
|
||||
>P : P
|
||||
>T : T
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
>Readonly : Readonly<T>
|
||||
>T : T
|
||||
|
||||
readonly [P in keyof T]: T[P];
|
||||
>P : P
|
||||
>T : T
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
>Pick : Pick<T, K>
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
|
||||
[P in K]: T[P];
|
||||
>P : P
|
||||
>K : K
|
||||
>T : T
|
||||
>P : P
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
>Record : Record<K, T>
|
||||
>K : K
|
||||
>T : T
|
||||
|
||||
[_ in K]: T;
|
||||
>_ : _
|
||||
>K : K
|
||||
>T : T
|
||||
}
|
||||
|
||||
type Proxy<T> = {
|
||||
>Proxy : Proxy<T>
|
||||
>T : T
|
||||
|
||||
get(): T;
|
||||
>get : () => T
|
||||
>T : T
|
||||
|
||||
set(value: T): void;
|
||||
>set : (value: T) => void
|
||||
>value : T
|
||||
>T : T
|
||||
}
|
||||
|
||||
type Proxify<T> = {
|
||||
>Proxify : Proxify<T>
|
||||
>T : T
|
||||
|
||||
[P in keyof T]: Proxy<T[P]>;
|
||||
>P : P
|
||||
>T : T
|
||||
>Proxy : Proxy<T>
|
||||
>T : T
|
||||
>P : P
|
||||
}
|
||||
|
||||
type DeepReadonly<T> = {
|
||||
>DeepReadonly : DeepReadonly<T>
|
||||
>T : T
|
||||
|
||||
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
||||
>P : P
|
||||
>T : T
|
||||
>DeepReadonly : DeepReadonly<T>
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
};
|
||||
|
||||
declare function assign<T>(obj: T, props: Partial<T>): void;
|
||||
>assign : <T>(obj: T, props: Partial<T>) => void
|
||||
>T : T
|
||||
>obj : T
|
||||
>T : T
|
||||
>props : Partial<T>
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
|
||||
declare function freeze<T>(obj: T): Readonly<T>;
|
||||
>freeze : <T>(obj: T) => Readonly<T>
|
||||
>T : T
|
||||
>obj : T
|
||||
>T : T
|
||||
>Readonly : Readonly<T>
|
||||
>T : T
|
||||
|
||||
declare function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;
|
||||
>pick : <T, K extends keyof T>(obj: T, ...keys: K[]) => Pick<T, K>
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>obj : T
|
||||
>T : T
|
||||
>keys : K[]
|
||||
>K : K
|
||||
>Pick : Pick<T, K>
|
||||
>T : T
|
||||
>K : K
|
||||
|
||||
declare function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>;
|
||||
>mapObject : <K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U) => Record<K, U>
|
||||
>K : K
|
||||
>T : T
|
||||
>U : U
|
||||
>obj : Record<K, T>
|
||||
>Record : Record<K, T>
|
||||
>K : K
|
||||
>T : T
|
||||
>f : (x: T) => U
|
||||
>x : T
|
||||
>T : T
|
||||
>U : U
|
||||
>Record : Record<K, T>
|
||||
>K : K
|
||||
>U : U
|
||||
|
||||
declare function proxify<T>(obj: T): Proxify<T>;
|
||||
>proxify : <T>(obj: T) => Proxify<T>
|
||||
>T : T
|
||||
>obj : T
|
||||
>T : T
|
||||
>Proxify : Proxify<T>
|
||||
>T : T
|
||||
|
||||
interface Shape {
|
||||
>Shape : Shape
|
||||
|
||||
name: string;
|
||||
>name : string
|
||||
|
||||
width: number;
|
||||
>width : number
|
||||
|
||||
height: number;
|
||||
>height : number
|
||||
|
||||
visible: boolean;
|
||||
>visible : boolean
|
||||
}
|
||||
|
||||
interface PartialShape {
|
||||
>PartialShape : PartialShape
|
||||
|
||||
name?: string;
|
||||
>name : string | undefined
|
||||
|
||||
width?: number;
|
||||
>width : number | undefined
|
||||
|
||||
height?: number;
|
||||
>height : number | undefined
|
||||
|
||||
visible?: boolean;
|
||||
>visible : boolean | undefined
|
||||
}
|
||||
|
||||
interface ReadonlyShape {
|
||||
>ReadonlyShape : ReadonlyShape
|
||||
|
||||
readonly name: string;
|
||||
>name : string
|
||||
|
||||
readonly width: number;
|
||||
>width : number
|
||||
|
||||
readonly height: number;
|
||||
>height : number
|
||||
|
||||
readonly visible: boolean;
|
||||
>visible : boolean
|
||||
}
|
||||
|
||||
function f0(s1: Shape, s2: Shape) {
|
||||
>f0 : (s1: Shape, s2: Shape) => void
|
||||
>s1 : Shape
|
||||
>Shape : Shape
|
||||
>s2 : Shape
|
||||
>Shape : Shape
|
||||
|
||||
assign(s1, { name: "circle" });
|
||||
>assign(s1, { name: "circle" }) : void
|
||||
>assign : <T>(obj: T, props: Partial<T>) => void
|
||||
>s1 : Shape
|
||||
>{ name: "circle" } : { name: string; }
|
||||
>name : string
|
||||
>"circle" : "circle"
|
||||
|
||||
assign(s2, { width: 10, height: 20 });
|
||||
>assign(s2, { width: 10, height: 20 }) : void
|
||||
>assign : <T>(obj: T, props: Partial<T>) => void
|
||||
>s2 : Shape
|
||||
>{ width: 10, height: 20 } : { width: number; height: number; }
|
||||
>width : number
|
||||
>10 : 10
|
||||
>height : number
|
||||
>20 : 20
|
||||
}
|
||||
|
||||
function f1(shape: Shape) {
|
||||
>f1 : (shape: Shape) => void
|
||||
>shape : Shape
|
||||
>Shape : Shape
|
||||
|
||||
var frozen: ReadonlyShape;
|
||||
>frozen : ReadonlyShape
|
||||
>ReadonlyShape : ReadonlyShape
|
||||
|
||||
var frozen: Readonly<Shape>;
|
||||
>frozen : ReadonlyShape
|
||||
>Readonly : Readonly<T>
|
||||
>Shape : Shape
|
||||
|
||||
var frozen = freeze(shape);
|
||||
>frozen : ReadonlyShape
|
||||
>freeze(shape) : Readonly<Shape>
|
||||
>freeze : <T>(obj: T) => Readonly<T>
|
||||
>shape : Shape
|
||||
}
|
||||
|
||||
function f2(shape: Shape) {
|
||||
>f2 : (shape: Shape) => void
|
||||
>shape : Shape
|
||||
>Shape : Shape
|
||||
|
||||
var partial: PartialShape;
|
||||
>partial : PartialShape
|
||||
>PartialShape : PartialShape
|
||||
|
||||
var partial: Partial<Shape>;
|
||||
>partial : PartialShape
|
||||
>Partial : Partial<T>
|
||||
>Shape : Shape
|
||||
|
||||
var partial: Partial<Shape> = {};
|
||||
>partial : PartialShape
|
||||
>Partial : Partial<T>
|
||||
>Shape : Shape
|
||||
>{} : {}
|
||||
}
|
||||
|
||||
function f3(shape: Shape) {
|
||||
>f3 : (shape: Shape) => void
|
||||
>shape : Shape
|
||||
>Shape : Shape
|
||||
|
||||
const x = pick(shape, "name", "visible"); // { name: string, visible: boolean }
|
||||
>x : Pick<Shape, "name" | "visible">
|
||||
>pick(shape, "name", "visible") : Pick<Shape, "name" | "visible">
|
||||
>pick : <T, K extends keyof T>(obj: T, ...keys: K[]) => Pick<T, K>
|
||||
>shape : Shape
|
||||
>"name" : "name"
|
||||
>"visible" : "visible"
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : () => void
|
||||
|
||||
const rec = { foo: "hello", bar: "world", baz: "bye" };
|
||||
>rec : { foo: string; bar: string; baz: string; }
|
||||
>{ foo: "hello", bar: "world", baz: "bye" } : { foo: string; bar: string; baz: string; }
|
||||
>foo : string
|
||||
>"hello" : "hello"
|
||||
>bar : string
|
||||
>"world" : "world"
|
||||
>baz : string
|
||||
>"bye" : "bye"
|
||||
|
||||
const lengths = mapObject(rec, s => s.length); // { foo: number, bar: number, baz: number }
|
||||
>lengths : Record<"foo" | "bar" | "baz", number>
|
||||
>mapObject(rec, s => s.length) : Record<"foo" | "bar" | "baz", number>
|
||||
>mapObject : <K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U) => Record<K, U>
|
||||
>rec : { foo: string; bar: string; baz: string; }
|
||||
>s => s.length : (s: string) => number
|
||||
>s : string
|
||||
>s.length : number
|
||||
>s : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function f5(shape: Shape) {
|
||||
>f5 : (shape: Shape) => void
|
||||
>shape : Shape
|
||||
>Shape : Shape
|
||||
|
||||
const p = proxify(shape);
|
||||
>p : Proxify<Shape>
|
||||
>proxify(shape) : Proxify<Shape>
|
||||
>proxify : <T>(obj: T) => Proxify<T>
|
||||
>shape : Shape
|
||||
|
||||
let name = p.name.get();
|
||||
>name : string
|
||||
>p.name.get() : string
|
||||
>p.name.get : () => string
|
||||
>p.name : Proxy<string>
|
||||
>p : Proxify<Shape>
|
||||
>name : Proxy<string>
|
||||
>get : () => string
|
||||
|
||||
p.visible.set(false);
|
||||
>p.visible.set(false) : void
|
||||
>p.visible.set : (value: boolean) => void
|
||||
>p.visible : Proxy<boolean>
|
||||
>p : Proxify<Shape>
|
||||
>visible : Proxy<boolean>
|
||||
>set : (value: boolean) => void
|
||||
>false : false
|
||||
}
|
||||
|
||||
function f6(shape: DeepReadonly<Shape>) {
|
||||
>f6 : (shape: DeepReadonly<Shape>) => void
|
||||
>shape : DeepReadonly<Shape>
|
||||
>DeepReadonly : DeepReadonly<T>
|
||||
>Shape : Shape
|
||||
|
||||
let name = shape.name; // DeepReadonly<string>
|
||||
>name : DeepReadonly<string>
|
||||
>shape.name : DeepReadonly<string>
|
||||
>shape : DeepReadonly<Shape>
|
||||
>name : DeepReadonly<string>
|
||||
|
||||
let length = name.length; // DeepReadonly<number>
|
||||
>length : DeepReadonly<number>
|
||||
>name.length : DeepReadonly<number>
|
||||
>name : DeepReadonly<string>
|
||||
>length : DeepReadonly<number>
|
||||
|
||||
let toString = length.toString; // DeepReadonly<(radix?: number) => string>
|
||||
>toString : DeepReadonly<(radix?: number | undefined) => string>
|
||||
>length.toString : DeepReadonly<(radix?: number | undefined) => string>
|
||||
>length : DeepReadonly<number>
|
||||
>toString : DeepReadonly<(radix?: number | undefined) => string>
|
||||
}
|
84
tests/baselines/reference/mappedTypes3.js
Normal file
84
tests/baselines/reference/mappedTypes3.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
//// [mappedTypes3.ts]
|
||||
|
||||
class Box<P> {
|
||||
value: P;
|
||||
}
|
||||
|
||||
type Boxified<T> = {
|
||||
[K in keyof T]: Box<T[K]>;
|
||||
}
|
||||
|
||||
declare function boxify<T>(obj: T): Boxified<T>;
|
||||
declare function unboxify<T>(obj: Boxified<T>): T;
|
||||
|
||||
interface Bacon {
|
||||
isPerfect: boolean;
|
||||
weight: number;
|
||||
}
|
||||
|
||||
interface BoxifiedBacon {
|
||||
isPerfect: Box<boolean>;
|
||||
weight: Box<number>;
|
||||
}
|
||||
|
||||
function f1(b: Bacon) {
|
||||
let bb = boxify(b);
|
||||
let isPerfect = bb.isPerfect.value;
|
||||
let weight = bb.weight.value;
|
||||
}
|
||||
|
||||
function f2(bb: Boxified<Bacon>) {
|
||||
let b = unboxify(bb); // Infer Bacon for T
|
||||
let bool = b.isPerfect;
|
||||
let weight = b.weight;
|
||||
}
|
||||
|
||||
function f3(bb: BoxifiedBacon) {
|
||||
let b = unboxify<Bacon>(bb); // Explicit type parameter required
|
||||
let bool = b.isPerfect;
|
||||
let weight = bb.weight;
|
||||
}
|
||||
|
||||
//// [mappedTypes3.js]
|
||||
var Box = (function () {
|
||||
function Box() {
|
||||
}
|
||||
return Box;
|
||||
}());
|
||||
function f1(b) {
|
||||
var bb = boxify(b);
|
||||
var isPerfect = bb.isPerfect.value;
|
||||
var weight = bb.weight.value;
|
||||
}
|
||||
function f2(bb) {
|
||||
var b = unboxify(bb); // Infer Bacon for T
|
||||
var bool = b.isPerfect;
|
||||
var weight = b.weight;
|
||||
}
|
||||
function f3(bb) {
|
||||
var b = unboxify(bb); // Explicit type parameter required
|
||||
var bool = b.isPerfect;
|
||||
var weight = bb.weight;
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypes3.d.ts]
|
||||
declare class Box<P> {
|
||||
value: P;
|
||||
}
|
||||
declare type Boxified<T> = {
|
||||
[K in keyof T]: Box<T[K]>;
|
||||
};
|
||||
declare function boxify<T>(obj: T): Boxified<T>;
|
||||
declare function unboxify<T>(obj: Boxified<T>): T;
|
||||
interface Bacon {
|
||||
isPerfect: boolean;
|
||||
weight: number;
|
||||
}
|
||||
interface BoxifiedBacon {
|
||||
isPerfect: Box<boolean>;
|
||||
weight: Box<number>;
|
||||
}
|
||||
declare function f1(b: Bacon): void;
|
||||
declare function f2(bb: Boxified<Bacon>): void;
|
||||
declare function f3(bb: BoxifiedBacon): void;
|
135
tests/baselines/reference/mappedTypes3.symbols
Normal file
135
tests/baselines/reference/mappedTypes3.symbols
Normal file
|
@ -0,0 +1,135 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes3.ts ===
|
||||
|
||||
class Box<P> {
|
||||
>Box : Symbol(Box, Decl(mappedTypes3.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(mappedTypes3.ts, 1, 10))
|
||||
|
||||
value: P;
|
||||
>value : Symbol(Box.value, Decl(mappedTypes3.ts, 1, 14))
|
||||
>P : Symbol(P, Decl(mappedTypes3.ts, 1, 10))
|
||||
}
|
||||
|
||||
type Boxified<T> = {
|
||||
>Boxified : Symbol(Boxified, Decl(mappedTypes3.ts, 3, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 5, 14))
|
||||
|
||||
[K in keyof T]: Box<T[K]>;
|
||||
>K : Symbol(K, Decl(mappedTypes3.ts, 6, 5))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 5, 14))
|
||||
>Box : Symbol(Box, Decl(mappedTypes3.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 5, 14))
|
||||
>K : Symbol(K, Decl(mappedTypes3.ts, 6, 5))
|
||||
}
|
||||
|
||||
declare function boxify<T>(obj: T): Boxified<T>;
|
||||
>boxify : Symbol(boxify, Decl(mappedTypes3.ts, 7, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 9, 24))
|
||||
>obj : Symbol(obj, Decl(mappedTypes3.ts, 9, 27))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 9, 24))
|
||||
>Boxified : Symbol(Boxified, Decl(mappedTypes3.ts, 3, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 9, 24))
|
||||
|
||||
declare function unboxify<T>(obj: Boxified<T>): T;
|
||||
>unboxify : Symbol(unboxify, Decl(mappedTypes3.ts, 9, 48))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 10, 26))
|
||||
>obj : Symbol(obj, Decl(mappedTypes3.ts, 10, 29))
|
||||
>Boxified : Symbol(Boxified, Decl(mappedTypes3.ts, 3, 1))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 10, 26))
|
||||
>T : Symbol(T, Decl(mappedTypes3.ts, 10, 26))
|
||||
|
||||
interface Bacon {
|
||||
>Bacon : Symbol(Bacon, Decl(mappedTypes3.ts, 10, 50))
|
||||
|
||||
isPerfect: boolean;
|
||||
>isPerfect : Symbol(Bacon.isPerfect, Decl(mappedTypes3.ts, 12, 17))
|
||||
|
||||
weight: number;
|
||||
>weight : Symbol(Bacon.weight, Decl(mappedTypes3.ts, 13, 23))
|
||||
}
|
||||
|
||||
interface BoxifiedBacon {
|
||||
>BoxifiedBacon : Symbol(BoxifiedBacon, Decl(mappedTypes3.ts, 15, 1))
|
||||
|
||||
isPerfect: Box<boolean>;
|
||||
>isPerfect : Symbol(BoxifiedBacon.isPerfect, Decl(mappedTypes3.ts, 17, 25))
|
||||
>Box : Symbol(Box, Decl(mappedTypes3.ts, 0, 0))
|
||||
|
||||
weight: Box<number>;
|
||||
>weight : Symbol(BoxifiedBacon.weight, Decl(mappedTypes3.ts, 18, 28))
|
||||
>Box : Symbol(Box, Decl(mappedTypes3.ts, 0, 0))
|
||||
}
|
||||
|
||||
function f1(b: Bacon) {
|
||||
>f1 : Symbol(f1, Decl(mappedTypes3.ts, 20, 1))
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 22, 12))
|
||||
>Bacon : Symbol(Bacon, Decl(mappedTypes3.ts, 10, 50))
|
||||
|
||||
let bb = boxify(b);
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 23, 7))
|
||||
>boxify : Symbol(boxify, Decl(mappedTypes3.ts, 7, 1))
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 22, 12))
|
||||
|
||||
let isPerfect = bb.isPerfect.value;
|
||||
>isPerfect : Symbol(isPerfect, Decl(mappedTypes3.ts, 24, 7))
|
||||
>bb.isPerfect.value : Symbol(Box.value, Decl(mappedTypes3.ts, 1, 14))
|
||||
>bb.isPerfect : Symbol(isPerfect)
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 23, 7))
|
||||
>isPerfect : Symbol(isPerfect)
|
||||
>value : Symbol(Box.value, Decl(mappedTypes3.ts, 1, 14))
|
||||
|
||||
let weight = bb.weight.value;
|
||||
>weight : Symbol(weight, Decl(mappedTypes3.ts, 25, 7))
|
||||
>bb.weight.value : Symbol(Box.value, Decl(mappedTypes3.ts, 1, 14))
|
||||
>bb.weight : Symbol(weight)
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 23, 7))
|
||||
>weight : Symbol(weight)
|
||||
>value : Symbol(Box.value, Decl(mappedTypes3.ts, 1, 14))
|
||||
}
|
||||
|
||||
function f2(bb: Boxified<Bacon>) {
|
||||
>f2 : Symbol(f2, Decl(mappedTypes3.ts, 26, 1))
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 28, 12))
|
||||
>Boxified : Symbol(Boxified, Decl(mappedTypes3.ts, 3, 1))
|
||||
>Bacon : Symbol(Bacon, Decl(mappedTypes3.ts, 10, 50))
|
||||
|
||||
let b = unboxify(bb); // Infer Bacon for T
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 29, 7))
|
||||
>unboxify : Symbol(unboxify, Decl(mappedTypes3.ts, 9, 48))
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 28, 12))
|
||||
|
||||
let bool = b.isPerfect;
|
||||
>bool : Symbol(bool, Decl(mappedTypes3.ts, 30, 7))
|
||||
>b.isPerfect : Symbol(Bacon.isPerfect, Decl(mappedTypes3.ts, 12, 17))
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 29, 7))
|
||||
>isPerfect : Symbol(Bacon.isPerfect, Decl(mappedTypes3.ts, 12, 17))
|
||||
|
||||
let weight = b.weight;
|
||||
>weight : Symbol(weight, Decl(mappedTypes3.ts, 31, 7))
|
||||
>b.weight : Symbol(Bacon.weight, Decl(mappedTypes3.ts, 13, 23))
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 29, 7))
|
||||
>weight : Symbol(Bacon.weight, Decl(mappedTypes3.ts, 13, 23))
|
||||
}
|
||||
|
||||
function f3(bb: BoxifiedBacon) {
|
||||
>f3 : Symbol(f3, Decl(mappedTypes3.ts, 32, 1))
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 34, 12))
|
||||
>BoxifiedBacon : Symbol(BoxifiedBacon, Decl(mappedTypes3.ts, 15, 1))
|
||||
|
||||
let b = unboxify<Bacon>(bb); // Explicit type parameter required
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 35, 7))
|
||||
>unboxify : Symbol(unboxify, Decl(mappedTypes3.ts, 9, 48))
|
||||
>Bacon : Symbol(Bacon, Decl(mappedTypes3.ts, 10, 50))
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 34, 12))
|
||||
|
||||
let bool = b.isPerfect;
|
||||
>bool : Symbol(bool, Decl(mappedTypes3.ts, 36, 7))
|
||||
>b.isPerfect : Symbol(Bacon.isPerfect, Decl(mappedTypes3.ts, 12, 17))
|
||||
>b : Symbol(b, Decl(mappedTypes3.ts, 35, 7))
|
||||
>isPerfect : Symbol(Bacon.isPerfect, Decl(mappedTypes3.ts, 12, 17))
|
||||
|
||||
let weight = bb.weight;
|
||||
>weight : Symbol(weight, Decl(mappedTypes3.ts, 37, 7))
|
||||
>bb.weight : Symbol(BoxifiedBacon.weight, Decl(mappedTypes3.ts, 18, 28))
|
||||
>bb : Symbol(bb, Decl(mappedTypes3.ts, 34, 12))
|
||||
>weight : Symbol(BoxifiedBacon.weight, Decl(mappedTypes3.ts, 18, 28))
|
||||
}
|
138
tests/baselines/reference/mappedTypes3.types
Normal file
138
tests/baselines/reference/mappedTypes3.types
Normal file
|
@ -0,0 +1,138 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypes3.ts ===
|
||||
|
||||
class Box<P> {
|
||||
>Box : Box<P>
|
||||
>P : P
|
||||
|
||||
value: P;
|
||||
>value : P
|
||||
>P : P
|
||||
}
|
||||
|
||||
type Boxified<T> = {
|
||||
>Boxified : Boxified<T>
|
||||
>T : T
|
||||
|
||||
[K in keyof T]: Box<T[K]>;
|
||||
>K : K
|
||||
>T : T
|
||||
>Box : Box<P>
|
||||
>T : T
|
||||
>K : K
|
||||
}
|
||||
|
||||
declare function boxify<T>(obj: T): Boxified<T>;
|
||||
>boxify : <T>(obj: T) => Boxified<T>
|
||||
>T : T
|
||||
>obj : T
|
||||
>T : T
|
||||
>Boxified : Boxified<T>
|
||||
>T : T
|
||||
|
||||
declare function unboxify<T>(obj: Boxified<T>): T;
|
||||
>unboxify : <T>(obj: Boxified<T>) => T
|
||||
>T : T
|
||||
>obj : Boxified<T>
|
||||
>Boxified : Boxified<T>
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
interface Bacon {
|
||||
>Bacon : Bacon
|
||||
|
||||
isPerfect: boolean;
|
||||
>isPerfect : boolean
|
||||
|
||||
weight: number;
|
||||
>weight : number
|
||||
}
|
||||
|
||||
interface BoxifiedBacon {
|
||||
>BoxifiedBacon : BoxifiedBacon
|
||||
|
||||
isPerfect: Box<boolean>;
|
||||
>isPerfect : Box<boolean>
|
||||
>Box : Box<P>
|
||||
|
||||
weight: Box<number>;
|
||||
>weight : Box<number>
|
||||
>Box : Box<P>
|
||||
}
|
||||
|
||||
function f1(b: Bacon) {
|
||||
>f1 : (b: Bacon) => void
|
||||
>b : Bacon
|
||||
>Bacon : Bacon
|
||||
|
||||
let bb = boxify(b);
|
||||
>bb : Boxified<Bacon>
|
||||
>boxify(b) : Boxified<Bacon>
|
||||
>boxify : <T>(obj: T) => Boxified<T>
|
||||
>b : Bacon
|
||||
|
||||
let isPerfect = bb.isPerfect.value;
|
||||
>isPerfect : boolean
|
||||
>bb.isPerfect.value : boolean
|
||||
>bb.isPerfect : Box<boolean>
|
||||
>bb : Boxified<Bacon>
|
||||
>isPerfect : Box<boolean>
|
||||
>value : boolean
|
||||
|
||||
let weight = bb.weight.value;
|
||||
>weight : number
|
||||
>bb.weight.value : number
|
||||
>bb.weight : Box<number>
|
||||
>bb : Boxified<Bacon>
|
||||
>weight : Box<number>
|
||||
>value : number
|
||||
}
|
||||
|
||||
function f2(bb: Boxified<Bacon>) {
|
||||
>f2 : (bb: Boxified<Bacon>) => void
|
||||
>bb : Boxified<Bacon>
|
||||
>Boxified : Boxified<T>
|
||||
>Bacon : Bacon
|
||||
|
||||
let b = unboxify(bb); // Infer Bacon for T
|
||||
>b : Bacon
|
||||
>unboxify(bb) : Bacon
|
||||
>unboxify : <T>(obj: Boxified<T>) => T
|
||||
>bb : Boxified<Bacon>
|
||||
|
||||
let bool = b.isPerfect;
|
||||
>bool : boolean
|
||||
>b.isPerfect : boolean
|
||||
>b : Bacon
|
||||
>isPerfect : boolean
|
||||
|
||||
let weight = b.weight;
|
||||
>weight : number
|
||||
>b.weight : number
|
||||
>b : Bacon
|
||||
>weight : number
|
||||
}
|
||||
|
||||
function f3(bb: BoxifiedBacon) {
|
||||
>f3 : (bb: BoxifiedBacon) => void
|
||||
>bb : BoxifiedBacon
|
||||
>BoxifiedBacon : BoxifiedBacon
|
||||
|
||||
let b = unboxify<Bacon>(bb); // Explicit type parameter required
|
||||
>b : Bacon
|
||||
>unboxify<Bacon>(bb) : Bacon
|
||||
>unboxify : <T>(obj: Boxified<T>) => T
|
||||
>Bacon : Bacon
|
||||
>bb : BoxifiedBacon
|
||||
|
||||
let bool = b.isPerfect;
|
||||
>bool : boolean
|
||||
>b.isPerfect : boolean
|
||||
>b : Bacon
|
||||
>isPerfect : boolean
|
||||
|
||||
let weight = bb.weight;
|
||||
>weight : Box<number>
|
||||
>bb.weight : Box<number>
|
||||
>bb : BoxifiedBacon
|
||||
>weight : Box<number>
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
tests/cases/compiler/noErrorTruncation.ts(10,7): error TS2322: Type '42' is not assignable to type '{ someLongOptionA: string; } | { someLongOptionB: string; } | { someLongOptionC: string; } | { someLongOptionD: string; } | { someLongOptionE: string; } | { someLongOptionF: string; }'.
|
||||
tests/cases/compiler/noErrorTruncation.ts(10,7): error TS2322: Type '42' is not assignable to type 'SomeLongOptionA | SomeLongOptionB | SomeLongOptionC | SomeLongOptionD | SomeLongOptionE | SomeLongOptionF'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noErrorTruncation.ts (1 errors) ====
|
||||
|
@ -13,7 +13,7 @@ tests/cases/compiler/noErrorTruncation.ts(10,7): error TS2322: Type '42' is not
|
|||
|
||||
const x: SomeLongOptionA
|
||||
~
|
||||
!!! error TS2322: Type '42' is not assignable to type '{ someLongOptionA: string; } | { someLongOptionB: string; } | { someLongOptionC: string; } | { someLongOptionD: string; } | { someLongOptionE: string; } | { someLongOptionF: string; }'.
|
||||
!!! error TS2322: Type '42' is not assignable to type 'SomeLongOptionA | SomeLongOptionB | SomeLongOptionC | SomeLongOptionD | SomeLongOptionE | SomeLongOptionF'.
|
||||
| SomeLongOptionB
|
||||
| SomeLongOptionC
|
||||
| SomeLongOptionD
|
||||
|
|
|
@ -8,7 +8,7 @@ import { IEventSourcedEntity } from "./bar";
|
|||
>IEventSourcedEntity : any
|
||||
|
||||
export type DomainEntityConstructor<TEntity extends IEventSourcedEntity> = { new(): TEntity; };
|
||||
>DomainEntityConstructor : new () => TEntity
|
||||
>DomainEntityConstructor : DomainEntityConstructor<TEntity>
|
||||
>TEntity : TEntity
|
||||
>IEventSourcedEntity : IEventSourcedEntity
|
||||
>TEntity : TEntity
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
=== tests/cases/compiler/typeAliasDeclarationEmit2.ts ===
|
||||
|
||||
export type A<a> = { value: a };
|
||||
>A : { value: a; }
|
||||
>A : A<a>
|
||||
>a : a
|
||||
>value : a
|
||||
>a : a
|
||||
|
|
|
@ -104,7 +104,7 @@ var x9: T9;
|
|||
>T9 : T9
|
||||
|
||||
type T10 = { x: number };
|
||||
>T10 : { x: number; }
|
||||
>T10 : T10
|
||||
>x : number
|
||||
|
||||
var x10: { x: number };
|
||||
|
@ -113,17 +113,17 @@ var x10: { x: number };
|
|||
|
||||
var x10: T10;
|
||||
>x10 : { x: number; }
|
||||
>T10 : { x: number; }
|
||||
>T10 : T10
|
||||
|
||||
type T11 = { new(): boolean };
|
||||
>T11 : new () => boolean
|
||||
>T11 : T11
|
||||
|
||||
var x11: { new(): boolean };
|
||||
>x11 : new () => boolean
|
||||
|
||||
var x11: T11;
|
||||
>x11 : new () => boolean
|
||||
>T11 : new () => boolean
|
||||
>T11 : T11
|
||||
|
||||
interface I13 { x: string };
|
||||
>I13 : I13
|
||||
|
|
|
@ -11,7 +11,7 @@ type TreeNode = {
|
|||
}
|
||||
|
||||
type TreeNodeMiddleman = {
|
||||
>TreeNodeMiddleman : { name: string; parent: TreeNode; }
|
||||
>TreeNodeMiddleman : TreeNodeMiddleman
|
||||
|
||||
name: string;
|
||||
>name : string
|
||||
|
@ -22,17 +22,17 @@ type TreeNodeMiddleman = {
|
|||
}
|
||||
|
||||
var nodes: TreeNodeMiddleman[];
|
||||
>nodes : { name: string; parent: TreeNode; }[]
|
||||
>TreeNodeMiddleman : { name: string; parent: TreeNode; }
|
||||
>nodes : TreeNodeMiddleman[]
|
||||
>TreeNodeMiddleman : TreeNodeMiddleman
|
||||
|
||||
nodes.map(n => n.name);
|
||||
>nodes.map(n => n.name) : string[]
|
||||
>nodes.map : { <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): U[]; }
|
||||
>nodes : { name: string; parent: TreeNode; }[]
|
||||
>map : { <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U, U]; <U>(this: [{ name: string; parent: TreeNode; }, { name: string; parent: TreeNode; }], callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any): U[]; }
|
||||
>n => n.name : (n: { name: string; parent: TreeNode; }) => string
|
||||
>n : { name: string; parent: TreeNode; }
|
||||
>nodes.map : { <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): U[]; }
|
||||
>nodes : TreeNodeMiddleman[]
|
||||
>map : { <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U, U]; <U>(this: [TreeNodeMiddleman, TreeNodeMiddleman], callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: TreeNodeMiddleman, index: number, array: TreeNodeMiddleman[]) => U, thisArg?: any): U[]; }
|
||||
>n => n.name : (n: TreeNodeMiddleman) => string
|
||||
>n : TreeNodeMiddleman
|
||||
>n.name : string
|
||||
>n : { name: string; parent: TreeNode; }
|
||||
>n : TreeNodeMiddleman
|
||||
>name : string
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts ===
|
||||
type Tag = {__tag: any};
|
||||
>Tag : { __tag: any; }
|
||||
>Tag : Tag
|
||||
>__tag : any
|
||||
|
||||
declare function isNonBlank(value: string) : value is (string & Tag);
|
||||
>isNonBlank : (value: string) => value is string & { __tag: any; }
|
||||
>isNonBlank : (value: string) => value is string & Tag
|
||||
>value : string
|
||||
>value : any
|
||||
>Tag : { __tag: any; }
|
||||
>Tag : Tag
|
||||
|
||||
declare function doThis(value: string & Tag): void;
|
||||
>doThis : (value: string & { __tag: any; }) => void
|
||||
>value : string & { __tag: any; }
|
||||
>Tag : { __tag: any; }
|
||||
>doThis : (value: string & Tag) => void
|
||||
>value : string & Tag
|
||||
>Tag : Tag
|
||||
|
||||
declare function doThat(value: string) : void;
|
||||
>doThat : (value: string) => void
|
||||
|
@ -23,13 +23,13 @@ let value: string;
|
|||
|
||||
if (isNonBlank(value)) {
|
||||
>isNonBlank(value) : boolean
|
||||
>isNonBlank : (value: string) => value is string & { __tag: any; }
|
||||
>isNonBlank : (value: string) => value is string & Tag
|
||||
>value : string
|
||||
|
||||
doThis(value);
|
||||
>doThis(value) : void
|
||||
>doThis : (value: string & { __tag: any; }) => void
|
||||
>value : string & { __tag: any; }
|
||||
>doThis : (value: string & Tag) => void
|
||||
>value : string & Tag
|
||||
|
||||
} else {
|
||||
doThat(value);
|
||||
|
|
62
tests/cases/conformance/types/mapped/mappedTypeErrors.ts
Normal file
62
tests/cases/conformance/types/mapped/mappedTypeErrors.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
}
|
||||
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface Named {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
type T00 = { [P in P]: string }; // Error
|
||||
type T01 = { [P in Date]: number }; // Error
|
||||
type T02 = Record<Date, number>; // Error
|
||||
|
||||
type T10 = Pick<Shape, "name">;
|
||||
type T11 = Pick<Shape, "foo">; // Error
|
||||
type T12 = Pick<Shape, "name" | "foo">; // Error
|
||||
type T13 = Pick<Shape, keyof Named>;
|
||||
type T14 = Pick<Shape, keyof Point>; // Error
|
||||
type T15 = Pick<Shape, never>;
|
||||
type T16 = Pick<Shape, undefined>; // Error
|
||||
|
||||
function f1<T>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
}
|
||||
|
||||
function f2<T extends string | number>(x: T) {
|
||||
let y: Pick<Shape, T>; // Error
|
||||
}
|
||||
|
||||
function f3<T extends keyof Shape>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
||||
|
||||
function f4<T extends keyof Named>(x: T) {
|
||||
let y: Pick<Shape, T>;
|
||||
}
|
44
tests/cases/conformance/types/mapped/mappedTypes1.ts
Normal file
44
tests/cases/conformance/types/mapped/mappedTypes1.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
type Item = { a: string, b: number, c: boolean };
|
||||
|
||||
type T00 = { [P in "x" | "y"]: number };
|
||||
type T01 = { [P in "x" | "y"]: P };
|
||||
type T02 = { [P in "a" | "b"]: Item[P]; }
|
||||
type T03 = { [P in keyof Item]: Date };
|
||||
|
||||
type T10 = { [P in keyof Item]: Item[P] };
|
||||
type T11 = { [P in keyof Item]?: Item[P] };
|
||||
type T12 = { readonly [P in keyof Item]: Item[P] };
|
||||
type T13 = { readonly [P in keyof Item]?: Item[P] };
|
||||
|
||||
type T20 = { [P in keyof Item]: Item[P] | null };
|
||||
type T21 = { [P in keyof Item]: Array<Item[P]> };
|
||||
|
||||
type T30 = { [P in keyof any]: void };
|
||||
type T31 = { [P in keyof string]: void };
|
||||
type T32 = { [P in keyof number]: void };
|
||||
type T33 = { [P in keyof boolean]: void };
|
||||
type T34 = { [P in keyof undefined]: void };
|
||||
type T35 = { [P in keyof null]: void };
|
||||
type T36 = { [P in keyof void]: void };
|
||||
type T37 = { [P in keyof symbol]: void };
|
||||
type T38 = { [P in keyof never]: void };
|
||||
|
||||
type T40 = { [P in string]: void };
|
||||
type T41 = { [P in number]: void };
|
||||
type T42 = { [P in string | number]: void };
|
||||
type T43 = { [P in "a" | "b" | 0 | 1]: void };
|
||||
type T44 = { [P in "a" | "b" | "0" | "1"]: void };
|
||||
type T45 = { [P in "a" | "b" | "0" | "1" | 0 | 1]: void };
|
||||
type T46 = { [P in number | "a" | "b" | 0 | 1]: void };
|
||||
type T47 = { [P in string | number | "a" | "b" | 0 | 1]: void };
|
||||
|
||||
declare function f1<T1>(): { [P in keyof T1]: void };
|
||||
declare function f2<T1 extends string>(): { [P in keyof T1]: void };
|
||||
declare function f3<T1 extends number>(): { [P in keyof T1]: void };
|
||||
|
||||
let x1 = f1();
|
||||
let x2 = f2();
|
||||
let x3 = f3();
|
96
tests/cases/conformance/types/mapped/mappedTypes2.ts
Normal file
96
tests/cases/conformance/types/mapped/mappedTypes2.ts
Normal file
|
@ -0,0 +1,96 @@
|
|||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
type Partial<T> = {
|
||||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
type Readonly<T> = {
|
||||
readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
}
|
||||
|
||||
type Record<K extends string | number, T> = {
|
||||
[_ in K]: T;
|
||||
}
|
||||
|
||||
type Proxy<T> = {
|
||||
get(): T;
|
||||
set(value: T): void;
|
||||
}
|
||||
|
||||
type Proxify<T> = {
|
||||
[P in keyof T]: Proxy<T[P]>;
|
||||
}
|
||||
|
||||
type DeepReadonly<T> = {
|
||||
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
||||
};
|
||||
|
||||
declare function assign<T>(obj: T, props: Partial<T>): void;
|
||||
declare function freeze<T>(obj: T): Readonly<T>;
|
||||
declare function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;
|
||||
declare function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>;
|
||||
declare function proxify<T>(obj: T): Proxify<T>;
|
||||
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface PartialShape {
|
||||
name?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
interface ReadonlyShape {
|
||||
readonly name: string;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly visible: boolean;
|
||||
}
|
||||
|
||||
function f0(s1: Shape, s2: Shape) {
|
||||
assign(s1, { name: "circle" });
|
||||
assign(s2, { width: 10, height: 20 });
|
||||
}
|
||||
|
||||
function f1(shape: Shape) {
|
||||
var frozen: ReadonlyShape;
|
||||
var frozen: Readonly<Shape>;
|
||||
var frozen = freeze(shape);
|
||||
}
|
||||
|
||||
function f2(shape: Shape) {
|
||||
var partial: PartialShape;
|
||||
var partial: Partial<Shape>;
|
||||
var partial: Partial<Shape> = {};
|
||||
}
|
||||
|
||||
function f3(shape: Shape) {
|
||||
const x = pick(shape, "name", "visible"); // { name: string, visible: boolean }
|
||||
}
|
||||
|
||||
function f4() {
|
||||
const rec = { foo: "hello", bar: "world", baz: "bye" };
|
||||
const lengths = mapObject(rec, s => s.length); // { foo: number, bar: number, baz: number }
|
||||
}
|
||||
|
||||
function f5(shape: Shape) {
|
||||
const p = proxify(shape);
|
||||
let name = p.name.get();
|
||||
p.visible.set(false);
|
||||
}
|
||||
|
||||
function f6(shape: DeepReadonly<Shape>) {
|
||||
let name = shape.name; // DeepReadonly<string>
|
||||
let length = name.length; // DeepReadonly<number>
|
||||
let toString = length.toString; // DeepReadonly<(radix?: number) => string>
|
||||
}
|
40
tests/cases/conformance/types/mapped/mappedTypes3.ts
Normal file
40
tests/cases/conformance/types/mapped/mappedTypes3.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
// @declaration: true
|
||||
|
||||
class Box<P> {
|
||||
value: P;
|
||||
}
|
||||
|
||||
type Boxified<T> = {
|
||||
[K in keyof T]: Box<T[K]>;
|
||||
}
|
||||
|
||||
declare function boxify<T>(obj: T): Boxified<T>;
|
||||
declare function unboxify<T>(obj: Boxified<T>): T;
|
||||
|
||||
interface Bacon {
|
||||
isPerfect: boolean;
|
||||
weight: number;
|
||||
}
|
||||
|
||||
interface BoxifiedBacon {
|
||||
isPerfect: Box<boolean>;
|
||||
weight: Box<number>;
|
||||
}
|
||||
|
||||
function f1(b: Bacon) {
|
||||
let bb = boxify(b);
|
||||
let isPerfect = bb.isPerfect.value;
|
||||
let weight = bb.weight.value;
|
||||
}
|
||||
|
||||
function f2(bb: Boxified<Bacon>) {
|
||||
let b = unboxify(bb); // Infer Bacon for T
|
||||
let bool = b.isPerfect;
|
||||
let weight = b.weight;
|
||||
}
|
||||
|
||||
function f3(bb: BoxifiedBacon) {
|
||||
let b = unboxify<Bacon>(bb); // Explicit type parameter required
|
||||
let bool = b.isPerfect;
|
||||
let weight = bb.weight;
|
||||
}
|
Loading…
Reference in a new issue