mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 06:41:59 -06:00
Template literal types and mapped type 'as' clauses (#40336)
* Initial implementation of string template types * Accept new API baselines * Accept new baselines * Unified checking for large cross product union types * Accept new baselines * Ensure errors from union type resolution are reported * Accept new baselines * Compute constraints for string template types * Support `as T` clause in mapped types * Accept new API baselines * Add missing semicolon * Add checking of `as T` clauses * Support casing modifiers in string template types * Accept new baselines * Bump keyword maximum length * fix anders * Revert "fix anders" This reverts commit b3178d46184c068b7b83008ad98a52faac1e8a34. * Properly handle 'as T' clause with keyof for mapped type * Fix lint error * Single character inferences and anchored end span matching * Fewer array copy operations in template literal type resolution * Handle cases where 'as T' maps multiple properties onto one * Fix lint error * Store key type instead of type mapper in MappedSymbol * No constraint on `in T` type when `as N` clause present * Rename from TemplateType to TemplateLiteralType * Accept new API baselines * Add tests * Accept new baselines * Address CR feedback * Accept new API baselines Co-authored-by: Erich Gamma <egamma@microsoft.com>
This commit is contained in:
parent
96b0832cf6
commit
6f0c91c4cb
@ -698,6 +698,7 @@ namespace ts {
|
||||
const intersectionTypes = new Map<string, Type>();
|
||||
const literalTypes = new Map<string, LiteralType>();
|
||||
const indexedAccessTypes = new Map<string, IndexedAccessType>();
|
||||
const templateLiteralTypes = new Map<string, TemplateLiteralType>();
|
||||
const substitutionTypes = new Map<string, SubstitutionType>();
|
||||
const evolvingArrayTypes: EvolvingArrayType[] = [];
|
||||
const undefinedProperties: SymbolTable = new Map();
|
||||
@ -748,6 +749,7 @@ namespace ts {
|
||||
const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
|
||||
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
|
||||
const numberOrBigIntType = getUnionType([numberType, bigintType]);
|
||||
const templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType]);
|
||||
|
||||
const restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(<TypeParameter>t) : t);
|
||||
const permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t);
|
||||
@ -4489,6 +4491,19 @@ namespace ts {
|
||||
const indexTypeNode = typeToTypeNodeHelper(indexedType, context);
|
||||
return factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, indexTypeNode);
|
||||
}
|
||||
if (type.flags & TypeFlags.TemplateLiteral) {
|
||||
const texts = (<TemplateLiteralType>type).texts;
|
||||
const casings = (<TemplateLiteralType>type).casings;
|
||||
const types = (<TemplateLiteralType>type).types;
|
||||
const templateHead = factory.createTemplateHead(texts[0]);
|
||||
const templateSpans = factory.createNodeArray(
|
||||
map(types, (t, i) => factory.createTemplateLiteralTypeSpan(
|
||||
casings[i],
|
||||
typeToTypeNodeHelper(t, context),
|
||||
(i < types.length - 1 ? factory.createTemplateMiddle : factory.createTemplateTail)(texts[i + 1]))));
|
||||
context.approximateLength += 2;
|
||||
return factory.createTemplateLiteralType(templateHead, templateSpans);
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
const objectTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).objectType, context);
|
||||
const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
|
||||
@ -4541,8 +4556,9 @@ namespace ts {
|
||||
appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
|
||||
}
|
||||
const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
|
||||
const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined;
|
||||
const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
|
||||
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
|
||||
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode);
|
||||
context.approximateLength += 10;
|
||||
return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
|
||||
}
|
||||
@ -10350,9 +10366,6 @@ namespace ts {
|
||||
// bound includes those keys that are known to always be present, for example because
|
||||
// because of constraints on type parameters (e.g. 'keyof T' for a constrained T).
|
||||
function getLowerBoundOfKeyType(type: Type): Type {
|
||||
if (type.flags & (TypeFlags.Any | TypeFlags.Primitive)) {
|
||||
return type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
const t = getApparentType((<IndexType>type).type);
|
||||
return isGenericTupleType(t) ? getKnownKeysOfTupleType(t) : getIndexType(t);
|
||||
@ -10373,7 +10386,7 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(sameMap((<UnionType>type).types, getLowerBoundOfKeyType));
|
||||
}
|
||||
return neverType;
|
||||
return type;
|
||||
}
|
||||
|
||||
/** Resolve the members of a mapped type { [P in K]: T } */
|
||||
@ -10387,6 +10400,7 @@ namespace ts {
|
||||
// and T as the template type.
|
||||
const typeParameter = getTypeParameterFromMappedType(type);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const nameType = getNameTypeFromMappedType(<MappedType>type.target || type);
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>type.target || type);
|
||||
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
|
||||
const templateModifiers = getMappedTypeModifiers(type);
|
||||
@ -10408,22 +10422,23 @@ namespace ts {
|
||||
}
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
|
||||
function addMemberForKeyType(t: Type) {
|
||||
// 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 templateMapper = appendTypeMapping(type.mapper, typeParameter, t);
|
||||
function addMemberForKeyType(keyType: Type) {
|
||||
const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType;
|
||||
forEachType(propNameType, t => addMemberForKeyTypeWorker(keyType, t));
|
||||
}
|
||||
|
||||
function addMemberForKeyTypeWorker(keyType: Type, propNameType: Type) {
|
||||
// If the current iteration type constituent is a string literal type, create a property.
|
||||
// Otherwise, for type string create a string index signature.
|
||||
if (isTypeUsableAsPropertyName(t)) {
|
||||
const propName = getPropertyNameFromType(t);
|
||||
if (isTypeUsableAsPropertyName(propNameType)) {
|
||||
const propName = getPropertyNameFromType(propNameType);
|
||||
// String enum members from separate enums with identical values
|
||||
// are distinct types with the same property name. Make the resulting
|
||||
// property symbol's name type be the union of those enum member types.
|
||||
const existingProp = members.get(propName) as MappedSymbol | undefined;
|
||||
if (existingProp) {
|
||||
existingProp.nameType = getUnionType([existingProp.nameType!, t]);
|
||||
existingProp.mapper = appendTypeMapping(type.mapper, typeParameter, existingProp.nameType);
|
||||
existingProp.nameType = getUnionType([existingProp.nameType!, propNameType]);
|
||||
existingProp.keyType = getUnionType([existingProp.keyType, keyType]);
|
||||
}
|
||||
else {
|
||||
const modifiersProp = getPropertyOfType(modifiersType, propName);
|
||||
@ -10435,19 +10450,20 @@ namespace ts {
|
||||
const prop = <MappedSymbol>createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName,
|
||||
CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0));
|
||||
prop.mappedType = type;
|
||||
prop.nameType = propNameType;
|
||||
prop.keyType = keyType;
|
||||
if (modifiersProp) {
|
||||
prop.syntheticOrigin = modifiersProp;
|
||||
prop.declarations = modifiersProp.declarations;
|
||||
}
|
||||
prop.nameType = t;
|
||||
prop.mapper = templateMapper;
|
||||
members.set(propName, prop);
|
||||
}
|
||||
}
|
||||
else if (t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) {
|
||||
const propType = instantiateType(templateType, templateMapper);
|
||||
if (t.flags & (TypeFlags.Any | TypeFlags.String)) {
|
||||
stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) {
|
||||
const propType = instantiateType(templateType, appendTypeMapping(type.mapper, typeParameter, keyType));
|
||||
if (propNameType.flags & (TypeFlags.Any | TypeFlags.String)) {
|
||||
stringIndexInfo = createIndexInfo(stringIndexInfo ? getUnionType([stringIndexInfo.type, propType]) : propType,
|
||||
!!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
}
|
||||
else {
|
||||
numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType,
|
||||
@ -10459,12 +10475,14 @@ namespace ts {
|
||||
|
||||
function getTypeOfMappedSymbol(symbol: MappedSymbol) {
|
||||
if (!symbol.type) {
|
||||
const mappedType = symbol.mappedType;
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
symbol.mappedType.containsError = true;
|
||||
mappedType.containsError = true;
|
||||
return errorType;
|
||||
}
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>symbol.mappedType.target || symbol.mappedType);
|
||||
const propType = instantiateType(templateType, symbol.mapper);
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>mappedType.target || mappedType);
|
||||
const mapper = appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), symbol.keyType);
|
||||
const propType = instantiateType(templateType, mapper);
|
||||
// When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
|
||||
// type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
|
||||
// mode, if the underlying property is optional we remove 'undefined' from the type.
|
||||
@ -10472,11 +10490,10 @@ namespace ts {
|
||||
symbol.checkFlags & CheckFlags.StripOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
|
||||
propType;
|
||||
if (!popTypeResolution()) {
|
||||
error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(symbol.mappedType));
|
||||
error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType));
|
||||
type = errorType;
|
||||
}
|
||||
symbol.type = type;
|
||||
symbol.mapper = undefined!;
|
||||
}
|
||||
return symbol.type;
|
||||
}
|
||||
@ -10491,6 +10508,12 @@ namespace ts {
|
||||
(type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType);
|
||||
}
|
||||
|
||||
function getNameTypeFromMappedType(type: MappedType) {
|
||||
return type.declaration.nameType ?
|
||||
type.nameType || (type.nameType = instantiateType(getTypeFromTypeNode(type.declaration.nameType), type.mapper)) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function getTemplateTypeFromMappedType(type: MappedType) {
|
||||
return type.templateType ||
|
||||
(type.templateType = type.declaration.type ?
|
||||
@ -10784,7 +10807,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getBaseConstraintOfType(type: Type): Type | undefined {
|
||||
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
|
||||
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral)) {
|
||||
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
|
||||
return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
|
||||
}
|
||||
@ -10878,6 +10901,11 @@ namespace ts {
|
||||
if (t.flags & TypeFlags.Index) {
|
||||
return keyofConstraintType;
|
||||
}
|
||||
if (t.flags & TypeFlags.TemplateLiteral) {
|
||||
const types = (<TemplateLiteralType>t).types;
|
||||
const constraints = mapDefined(types, getBaseConstraint);
|
||||
return constraints.length === types.length ? getTemplateLiteralType((<TemplateLiteralType>t).texts, (<TemplateLiteralType>t).casings, constraints) : stringType;
|
||||
}
|
||||
if (t.flags & TypeFlags.IndexedAccess) {
|
||||
const baseObjectType = getBaseConstraint((<IndexedAccessType>t).objectType);
|
||||
const baseIndexType = getBaseConstraint((<IndexedAccessType>t).indexType);
|
||||
@ -10955,7 +10983,7 @@ namespace ts {
|
||||
|
||||
function getResolvedApparentTypeOfMappedType(type: MappedType) {
|
||||
const typeVariable = getHomomorphicTypeVariable(type);
|
||||
if (typeVariable) {
|
||||
if (typeVariable && !type.declaration.nameType) {
|
||||
const constraint = getConstraintOfTypeParameter(typeVariable);
|
||||
if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
|
||||
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
|
||||
@ -11895,6 +11923,11 @@ namespace ts {
|
||||
grandParent.kind === SyntaxKind.NamedTupleMember && (<NamedTupleMember>grandParent).dotDotDotToken) {
|
||||
inferences = append(inferences, createArrayType(unknownType));
|
||||
}
|
||||
// When an 'infer T' declaration is immediately contained in a string template type, we infer a 'string'
|
||||
// constraint.
|
||||
else if (grandParent.kind === SyntaxKind.TemplateLiteralTypeSpan) {
|
||||
inferences = append(inferences, stringType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12720,7 +12753,9 @@ namespace ts {
|
||||
// Transform [A, ...(X | Y | Z)] into [A, ...X] | [A, ...Y] | [A, ...Z]
|
||||
const unionIndex = findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ElementFlags.Variadic && t.flags & (TypeFlags.Never | TypeFlags.Union)));
|
||||
if (unionIndex >= 0) {
|
||||
return mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t)));
|
||||
return checkCrossProductUnion(map(elementTypes, (t, i) => target.elementFlags[i] & ElementFlags.Variadic ? t : unknownType)) ?
|
||||
mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t))) :
|
||||
errorType;
|
||||
}
|
||||
// If there are no variadic elements with non-generic types, just create a type reference with the same target type.
|
||||
const spreadIndex = findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ElementFlags.Variadic) && !(t.flags & TypeFlags.InstantiableNonPrimitive) && !isGenericMappedType(t));
|
||||
@ -13257,9 +13292,7 @@ namespace ts {
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
// If the estimated size of the resulting union type exceeds 100000 constituents, report an error.
|
||||
const size = reduceLeft(typeSet, (n, t) => n * (t.flags & TypeFlags.Union ? (<UnionType>t).types.length : 1), 1);
|
||||
if (size >= 100000) {
|
||||
error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
|
||||
if (!checkCrossProductUnion(typeSet)) {
|
||||
return errorType;
|
||||
}
|
||||
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
|
||||
@ -13276,6 +13309,15 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkCrossProductUnion(types: readonly Type[]) {
|
||||
const size = reduceLeft(types, (n, t) => n * (t.flags & TypeFlags.Union ? (<UnionType>t).types.length : t.flags & TypeFlags.Never ? 0 : 1), 1);
|
||||
if (size >= 100000) {
|
||||
error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
@ -13299,6 +13341,13 @@ namespace ts {
|
||||
type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false));
|
||||
}
|
||||
|
||||
function getIndexTypeForMappedType(type: MappedType, noIndexSignatures: boolean | undefined) {
|
||||
const constraint = filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String)));
|
||||
return type.declaration.nameType ?
|
||||
instantiateType(getTypeFromTypeNode(type.declaration.nameType), appendTypeMapping(type.mapper, getTypeParameterFromMappedType(type), constraint)) :
|
||||
constraint;
|
||||
}
|
||||
|
||||
function getLiteralTypeFromPropertyName(name: PropertyName) {
|
||||
if (isPrivateIdentifier(name)) {
|
||||
return neverType;
|
||||
@ -13347,7 +13396,7 @@ namespace ts {
|
||||
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? getIndexTypeForMappedType(<MappedType>type, noIndexSignatures) :
|
||||
type === wildcardType ? wildcardType :
|
||||
type.flags & TypeFlags.Unknown ? neverType :
|
||||
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
|
||||
@ -13392,6 +13441,83 @@ namespace ts {
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromTemplateTypeNode(node: TemplateLiteralTypeNode) {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getTemplateLiteralType(
|
||||
[node.head.text, ...map(node.templateSpans, span => span.literal.text)],
|
||||
map(node.templateSpans, span => span.casing),
|
||||
map(node.templateSpans, span => getTypeFromTypeNode(span.type)));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTemplateLiteralType(texts: readonly string[], casings: readonly TemplateCasing[], types: readonly Type[]): Type {
|
||||
const unionIndex = findIndex(types, t => !!(t.flags & (TypeFlags.Never | TypeFlags.Union)));
|
||||
if (unionIndex >= 0) {
|
||||
return checkCrossProductUnion(types) ?
|
||||
mapType(types[unionIndex], t => getTemplateLiteralType(texts, casings, replaceElement(types, unionIndex, t))) :
|
||||
errorType;
|
||||
}
|
||||
const newTypes = [];
|
||||
const newCasings = [];
|
||||
const newTexts = [];
|
||||
let text = texts[0];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const t = types[i];
|
||||
if (t.flags & TypeFlags.Literal) {
|
||||
const s = applyTemplateCasing(getTemplateStringForType(t) || "", casings[i]);
|
||||
text += s;
|
||||
text += texts[i + 1];
|
||||
}
|
||||
else if (isGenericIndexType(t)) {
|
||||
newTypes.push(t);
|
||||
newCasings.push(casings[i]);
|
||||
newTexts.push(text);
|
||||
text = texts[i + 1];
|
||||
}
|
||||
else {
|
||||
return stringType;
|
||||
}
|
||||
}
|
||||
if (newTypes.length === 0) {
|
||||
return getLiteralType(text);
|
||||
}
|
||||
newTexts.push(text);
|
||||
const id = `${getTypeListId(newTypes)}|${newCasings.join(",")}|${map(newTexts, t => t.length).join(",")}|${newTexts.join("")}`;
|
||||
let type = templateLiteralTypes.get(id);
|
||||
if (!type) {
|
||||
templateLiteralTypes.set(id, type = createTemplateLiteralType(newTexts, newCasings, newTypes));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTemplateStringForType(type: Type) {
|
||||
return type.flags & TypeFlags.StringLiteral ? (<StringLiteralType>type).value :
|
||||
type.flags & TypeFlags.NumberLiteral ? "" + (<NumberLiteralType>type).value :
|
||||
type.flags & TypeFlags.BigIntLiteral ? pseudoBigIntToString((<BigIntLiteralType>type).value) :
|
||||
type.flags & TypeFlags.BooleanLiteral ? (<IntrinsicType>type).intrinsicName :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function applyTemplateCasing(str: string, casing: TemplateCasing) {
|
||||
switch (casing) {
|
||||
case TemplateCasing.Uppercase: return str.toUpperCase();
|
||||
case TemplateCasing.Lowercase: return str.toLowerCase();
|
||||
case TemplateCasing.Capitalize: return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
case TemplateCasing.Uncapitalize: return str.charAt(0).toLowerCase() + str.slice(1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function createTemplateLiteralType(texts: readonly string[], casings: readonly TemplateCasing[], types: readonly Type[]) {
|
||||
const type = <TemplateLiteralType>createType(TypeFlags.TemplateLiteral);
|
||||
type.texts = texts;
|
||||
type.casings = casings;
|
||||
type.types = types;
|
||||
return type;
|
||||
}
|
||||
|
||||
function createIndexedAccessType(objectType: Type, indexType: Type, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined) {
|
||||
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
|
||||
type.objectType = objectType;
|
||||
@ -13624,7 +13750,7 @@ namespace ts {
|
||||
}
|
||||
return !!((<UnionOrIntersectionType>type).objectFlags & ObjectFlags.IsGenericIndexType);
|
||||
}
|
||||
return !!(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index));
|
||||
return !!(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral));
|
||||
}
|
||||
|
||||
function isThisTypeParameter(type: Type): boolean {
|
||||
@ -14122,7 +14248,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isEmptyObjectTypeOrSpreadsIntoEmptyObject(type: Type) {
|
||||
return isEmptyObjectType(type) || !!(type.flags & (TypeFlags.Null | TypeFlags.Undefined | TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index));
|
||||
return isEmptyObjectType(type) || !!(type.flags & (TypeFlags.Null | TypeFlags.Undefined | TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral));
|
||||
}
|
||||
|
||||
function isSinglePropertyAnonymousObjectType(type: Type) {
|
||||
@ -14208,7 +14334,7 @@ namespace ts {
|
||||
}
|
||||
return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
|
||||
}
|
||||
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
|
||||
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral)) {
|
||||
return left;
|
||||
}
|
||||
|
||||
@ -14540,6 +14666,8 @@ namespace ts {
|
||||
return getTypeFromConditionalTypeNode(<ConditionalTypeNode>node);
|
||||
case SyntaxKind.InferType:
|
||||
return getTypeFromInferTypeNode(<InferTypeNode>node);
|
||||
case SyntaxKind.TemplateLiteralType:
|
||||
return getTypeFromTemplateTypeNode(<TemplateLiteralTypeNode>node);
|
||||
case SyntaxKind.ImportType:
|
||||
return getTypeFromImportTypeNode(<ImportTypeNode>node);
|
||||
// This function assumes that an identifier, qualified name, or property access expression is a type expression
|
||||
@ -14837,13 +14965,18 @@ namespace ts {
|
||||
if (typeVariable !== mappedTypeVariable) {
|
||||
return mapType(getReducedType(mappedTypeVariable), t => {
|
||||
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) {
|
||||
if (isGenericTupleType(t)) {
|
||||
return instantiateMappedGenericTupleType(t, type, typeVariable, mapper);
|
||||
if (!type.declaration.nameType) {
|
||||
if (isArrayType(t)) {
|
||||
return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper));
|
||||
}
|
||||
if (isGenericTupleType(t)) {
|
||||
return instantiateMappedGenericTupleType(t, type, typeVariable, mapper);
|
||||
}
|
||||
if (isTupleType(t)) {
|
||||
return instantiateMappedTupleType(t, type, prependTypeMapping(typeVariable, t, mapper));
|
||||
}
|
||||
}
|
||||
const replacementMapper = prependTypeMapping(typeVariable, t, mapper);
|
||||
return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
|
||||
isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
|
||||
instantiateAnonymousType(type, replacementMapper);
|
||||
return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper));
|
||||
}
|
||||
return t;
|
||||
});
|
||||
@ -15001,6 +15134,9 @@ namespace ts {
|
||||
if (flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
if (flags & TypeFlags.TemplateLiteral) {
|
||||
return getTemplateLiteralType((<TemplateLiteralType>type).texts, (<TemplateLiteralType>type).casings, instantiateTypes((<TemplateLiteralType>type).types, mapper));
|
||||
}
|
||||
if (flags & TypeFlags.IndexedAccess) {
|
||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
@ -16987,7 +17123,8 @@ namespace ts {
|
||||
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q].
|
||||
if (getObjectFlags(source) & ObjectFlags.Mapped && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(<MappedType>source))) {
|
||||
if (getObjectFlags(source) & ObjectFlags.Mapped && !(<MappedType>source).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(<MappedType>source))) {
|
||||
|
||||
if (!(getMappedTypeModifiers(<MappedType>source) & MappedTypeModifiers.IncludeOptional)) {
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>source);
|
||||
const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(<MappedType>source));
|
||||
@ -17044,7 +17181,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isGenericMappedType(target)) {
|
||||
else if (isGenericMappedType(target) && !target.declaration.nameType) {
|
||||
// A source type T is related to a target type { [P in X]: T[P] }
|
||||
const template = getTemplateTypeFromMappedType(target);
|
||||
const modifiers = getMappedTypeModifiers(target);
|
||||
@ -17126,6 +17263,13 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.TemplateLiteral) {
|
||||
const constraint = getBaseConstraintOfType(source);
|
||||
if (constraint && (result = isRelatedTo(constraint, target, reportErrors))) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.Conditional) {
|
||||
if (target.flags & TypeFlags.Conditional) {
|
||||
// Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
|
||||
@ -17339,7 +17483,9 @@ namespace ts {
|
||||
const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers));
|
||||
if (result = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) {
|
||||
const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
|
||||
return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
|
||||
if (instantiateType(getNameTypeFromMappedType(source), mapper) === instantiateType(getNameTypeFromMappedType(target), mapper)) {
|
||||
return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ternary.False;
|
||||
@ -19575,6 +19721,9 @@ namespace ts {
|
||||
inferFromTypes(sourceType, target);
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.TemplateLiteral) {
|
||||
inferToTemplateLiteralType(source, <TemplateLiteralType>target);
|
||||
}
|
||||
else {
|
||||
source = getReducedType(source);
|
||||
if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) {
|
||||
@ -19627,8 +19776,8 @@ namespace ts {
|
||||
// We stop inferring and report a circularity if we encounter duplicate recursion identities on both
|
||||
// the source side and the target side.
|
||||
const saveExpandingFlags = expandingFlags;
|
||||
const sourceIdentity = getRecursionIdentity(source);
|
||||
const targetIdentity = getRecursionIdentity(target);
|
||||
const sourceIdentity = getRecursionIdentity(source) || source;
|
||||
const targetIdentity = getRecursionIdentity(target) || target;
|
||||
if (sourceIdentity && contains(sourceStack, sourceIdentity)) expandingFlags |= ExpandingFlags.Source;
|
||||
if (targetIdentity && contains(targetStack, targetIdentity)) expandingFlags |= ExpandingFlags.Target;
|
||||
if (expandingFlags !== ExpandingFlags.Both) {
|
||||
@ -19853,6 +20002,39 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function inferToTemplateLiteralType(source: Type, target: TemplateLiteralType) {
|
||||
if (source.flags & (TypeFlags.StringLike | TypeFlags.Index)) {
|
||||
const matches = source.flags & TypeFlags.StringLiteral ? inferLiteralsFromTemplateLiteralType(<StringLiteralType>source, target) :
|
||||
source.flags & TypeFlags.TemplateLiteral && arraysEqual((<TemplateLiteralType>source).texts, target.texts) && arraysEqual((<TemplateLiteralType>source).casings, target.casings)? (<TemplateLiteralType>source).types :
|
||||
undefined;
|
||||
const types = target.types;
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
inferFromTypes(matches ? matches[i] : source.flags & TypeFlags.StringLiteral ? neverType : stringType, types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inferLiteralsFromTemplateLiteralType(source: StringLiteralType, target: TemplateLiteralType): Type[] | undefined {
|
||||
const value = source.value;
|
||||
const texts = target.texts;
|
||||
const lastIndex = texts.length - 1;
|
||||
const startText = texts[0];
|
||||
const endText = texts[lastIndex];
|
||||
if (!(value.startsWith(startText) && value.endsWith(endText))) return undefined;
|
||||
const matches = [];
|
||||
const str = value.slice(startText.length, value.length - endText.length);
|
||||
let pos = 0;
|
||||
for (let i = 1; i < lastIndex; i++) {
|
||||
const delim = texts[i];
|
||||
const delimPos = delim.length > 0 ? str.indexOf(delim, pos) : pos < str.length ? pos + 1 : -1;
|
||||
if (delimPos < 0) return undefined;
|
||||
matches.push(getLiteralType(str.slice(pos, delimPos)));
|
||||
pos = delimPos + delim.length;
|
||||
}
|
||||
matches.push(getLiteralType(str.slice(pos)));
|
||||
return matches;
|
||||
}
|
||||
|
||||
function inferFromObjectTypes(source: Type, target: Type) {
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (
|
||||
(<TypeReference>source).target === (<TypeReference>target).target || isArrayType(source) && isArrayType(target))) {
|
||||
@ -19865,8 +20047,11 @@ namespace ts {
|
||||
// from S to T and from X to Y.
|
||||
inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
|
||||
inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
|
||||
const sourceNameType = getNameTypeFromMappedType(source);
|
||||
const targetNameType = getNameTypeFromMappedType(target);
|
||||
if (sourceNameType && targetNameType) inferFromTypes(sourceNameType, targetNameType);
|
||||
}
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped) {
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped && !(<MappedType>target).declaration.nameType) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
|
||||
if (inferToMappedType(source, <MappedType>target, constraintType)) {
|
||||
return;
|
||||
@ -20015,7 +20200,7 @@ namespace ts {
|
||||
|
||||
function hasPrimitiveConstraint(type: TypeParameter): boolean {
|
||||
const constraint = getConstraintOfTypeParameter(type);
|
||||
return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index);
|
||||
return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral);
|
||||
}
|
||||
|
||||
function isObjectLiteralType(type: Type) {
|
||||
@ -26059,7 +26244,7 @@ namespace ts {
|
||||
else {
|
||||
const contextualType = getIndexedAccessType(restType, getLiteralType(i - index));
|
||||
const argType = checkExpressionWithContextualType(arg, contextualType, context, checkMode);
|
||||
const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index);
|
||||
const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral);
|
||||
types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType));
|
||||
flags.push(ElementFlags.Required);
|
||||
}
|
||||
@ -29098,7 +29283,7 @@ namespace ts {
|
||||
// and the right operand to be of type Any, an object type, or a type parameter type.
|
||||
// The result is always of the Boolean primitive type.
|
||||
if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) ||
|
||||
isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TypeParameter))) {
|
||||
isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.TypeParameter))) {
|
||||
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
|
||||
}
|
||||
if (!allTypesAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) {
|
||||
@ -30047,7 +30232,7 @@ namespace ts {
|
||||
}
|
||||
// If the contextual type is a literal of a particular primitive type, we consider this a
|
||||
// literal context for all literals of that primitive type.
|
||||
return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
|
||||
return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index | TypeFlags.TemplateLiteral) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
|
||||
contextualType.flags & TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
|
||||
contextualType.flags & TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
|
||||
contextualType.flags & TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) ||
|
||||
@ -31206,10 +31391,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
forEach(node.elements, checkSourceElement);
|
||||
getTypeFromTypeNode(node);
|
||||
}
|
||||
|
||||
function checkUnionOrIntersectionType(node: UnionOrIntersectionTypeNode) {
|
||||
forEach(node.types, checkSourceElement);
|
||||
getTypeFromTypeNode(node);
|
||||
}
|
||||
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) {
|
||||
@ -31254,6 +31441,7 @@ namespace ts {
|
||||
|
||||
function checkMappedType(node: MappedTypeNode) {
|
||||
checkSourceElement(node.typeParameter);
|
||||
checkSourceElement(node.nameType);
|
||||
checkSourceElement(node.type);
|
||||
|
||||
if (!node.type) {
|
||||
@ -31261,8 +31449,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
const type = <MappedType>getTypeFromMappedTypeNode(node);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
checkTypeAssignableTo(constraintType, keyofConstraintType, getEffectiveConstraintOfTypeParameter(node.typeParameter));
|
||||
const nameType = getNameTypeFromMappedType(type);
|
||||
if (nameType) {
|
||||
checkTypeAssignableTo(nameType, keyofConstraintType, node.nameType);
|
||||
}
|
||||
else {
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
checkTypeAssignableTo(constraintType, keyofConstraintType, getEffectiveConstraintOfTypeParameter(node.typeParameter));
|
||||
}
|
||||
}
|
||||
|
||||
function checkThisType(node: ThisTypeNode) {
|
||||
@ -31286,6 +31480,18 @@ namespace ts {
|
||||
registerForUnusedIdentifiersCheck(node);
|
||||
}
|
||||
|
||||
function checkTemplateType(node: TemplateLiteralTypeNode) {
|
||||
forEachChild(node, checkSourceElement);
|
||||
getTypeFromTypeNode(node);
|
||||
for (const span of node.templateSpans) {
|
||||
const type = getTypeFromTypeNode(span.type);
|
||||
checkTypeAssignableTo(type, templateConstraintType, span.type);
|
||||
if (!everyType(type, t => !!(t.flags & TypeFlags.Literal) || isGenericIndexType(t))) {
|
||||
error(span.type, Diagnostics.Template_literal_type_argument_0_is_not_literal_type_or_a_generic_type, typeToString(type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkImportType(node: ImportTypeNode) {
|
||||
checkSourceElement(node.argument);
|
||||
getTypeFromTypeNode(node);
|
||||
@ -35897,6 +36103,8 @@ namespace ts {
|
||||
return checkConditionalType(<ConditionalTypeNode>node);
|
||||
case SyntaxKind.InferType:
|
||||
return checkInferType(<InferTypeNode>node);
|
||||
case SyntaxKind.TemplateLiteralType:
|
||||
return checkTemplateType(<TemplateLiteralTypeNode>node);
|
||||
case SyntaxKind.ImportType:
|
||||
return checkImportType(<ImportTypeNode>node);
|
||||
case SyntaxKind.NamedTupleMember:
|
||||
|
||||
@ -3028,6 +3028,10 @@
|
||||
"category": "Error",
|
||||
"code": 2792
|
||||
},
|
||||
"Template literal type argument '{0}' is not literal type or a generic type.": {
|
||||
"category": "Error",
|
||||
"code": 2793
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -1313,6 +1313,8 @@ namespace ts {
|
||||
return emitConstructSignature(<ConstructSignatureDeclaration>node);
|
||||
case SyntaxKind.IndexSignature:
|
||||
return emitIndexSignature(<IndexSignatureDeclaration>node);
|
||||
case SyntaxKind.TemplateLiteralTypeSpan:
|
||||
return emitTemplateTypeSpan(<TemplateLiteralTypeSpan>node);
|
||||
|
||||
// Types
|
||||
case SyntaxKind.TypePredicate:
|
||||
@ -1357,6 +1359,8 @@ namespace ts {
|
||||
return emitMappedType(<MappedTypeNode>node);
|
||||
case SyntaxKind.LiteralType:
|
||||
return emitLiteralType(<LiteralTypeNode>node);
|
||||
case SyntaxKind.TemplateLiteralType:
|
||||
return emitTemplateType(<TemplateLiteralTypeNode>node);
|
||||
case SyntaxKind.ImportType:
|
||||
return emitImportTypeNode(<ImportTypeNode>node);
|
||||
case SyntaxKind.JSDocAllType:
|
||||
@ -2010,6 +2014,20 @@ namespace ts {
|
||||
writeTrailingSemicolon();
|
||||
}
|
||||
|
||||
function emitTemplateTypeSpan(node: TemplateLiteralTypeSpan) {
|
||||
const keyword = node.casing === TemplateCasing.Uppercase ? "uppercase" :
|
||||
node.casing === TemplateCasing.Lowercase ? "lowercase" :
|
||||
node.casing === TemplateCasing.Capitalize ? "capitalize" :
|
||||
node.casing === TemplateCasing.Uncapitalize ? "uncapitalize" :
|
||||
undefined;
|
||||
if (keyword) {
|
||||
writeKeyword(keyword);
|
||||
writeSpace();
|
||||
}
|
||||
emit(node.type);
|
||||
emit(node.literal);
|
||||
}
|
||||
|
||||
function emitSemicolonClassElement() {
|
||||
writeTrailingSemicolon();
|
||||
}
|
||||
@ -2202,6 +2220,12 @@ namespace ts {
|
||||
writePunctuation("[");
|
||||
|
||||
pipelineEmit(EmitHint.MappedTypeParameter, node.typeParameter);
|
||||
if (node.nameType) {
|
||||
writeSpace();
|
||||
writeKeyword("as");
|
||||
writeSpace();
|
||||
emit(node.nameType);
|
||||
}
|
||||
|
||||
writePunctuation("]");
|
||||
if (node.questionToken) {
|
||||
@ -2228,6 +2252,11 @@ namespace ts {
|
||||
emitExpression(node.literal);
|
||||
}
|
||||
|
||||
function emitTemplateType(node: TemplateLiteralTypeNode) {
|
||||
emit(node.head);
|
||||
emitList(node, node.templateSpans, ListFormat.TemplateExpressionSpans);
|
||||
}
|
||||
|
||||
function emitImportTypeNode(node: ImportTypeNode) {
|
||||
if (node.isTypeOf) {
|
||||
writeKeyword("typeof");
|
||||
|
||||
@ -94,6 +94,8 @@ namespace ts {
|
||||
updateConstructSignature,
|
||||
createIndexSignature,
|
||||
updateIndexSignature,
|
||||
createTemplateLiteralTypeSpan,
|
||||
updateTemplateLiteralTypeSpan,
|
||||
createKeywordTypeNode,
|
||||
createTypePredicateNode,
|
||||
updateTypePredicateNode,
|
||||
@ -138,6 +140,8 @@ namespace ts {
|
||||
updateMappedTypeNode,
|
||||
createLiteralTypeNode,
|
||||
updateLiteralTypeNode,
|
||||
createTemplateLiteralType,
|
||||
updateTemplateLiteralType,
|
||||
createObjectBindingPattern,
|
||||
updateObjectBindingPattern,
|
||||
createArrayBindingPattern,
|
||||
@ -1600,6 +1604,25 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
// @api
|
||||
function createTemplateLiteralTypeSpan(casing: TemplateCasing, type: TypeNode, literal: TemplateMiddle | TemplateTail) {
|
||||
const node = createBaseNode<TemplateLiteralTypeSpan>(SyntaxKind.TemplateLiteralTypeSpan);
|
||||
node.casing = casing;
|
||||
node.type = type;
|
||||
node.literal = literal;
|
||||
node.transformFlags = TransformFlags.ContainsTypeScript;
|
||||
return node;
|
||||
}
|
||||
|
||||
// @api
|
||||
function updateTemplateLiteralTypeSpan(casing: TemplateCasing, node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail) {
|
||||
return node.casing !== casing
|
||||
|| node.type !== type
|
||||
|| node.literal !== literal
|
||||
? update(createTemplateLiteralTypeSpan(casing, type, literal), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
//
|
||||
// Types
|
||||
//
|
||||
@ -1891,6 +1914,23 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
// @api
|
||||
function createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) {
|
||||
const node = createBaseNode<TemplateLiteralTypeNode>(SyntaxKind.TemplateLiteralType);
|
||||
node.head = head;
|
||||
node.templateSpans = createNodeArray(templateSpans);
|
||||
node.transformFlags = TransformFlags.ContainsTypeScript;
|
||||
return node;
|
||||
}
|
||||
|
||||
// @api
|
||||
function updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) {
|
||||
return node.head !== head
|
||||
|| node.templateSpans !== templateSpans
|
||||
? update(createTemplateLiteralType(head, templateSpans), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
// @api
|
||||
function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf = false) {
|
||||
const node = createBaseNode<ImportTypeNode>(SyntaxKind.ImportType);
|
||||
@ -1968,10 +2008,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
// @api
|
||||
function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode {
|
||||
function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode {
|
||||
const node = createBaseNode<MappedTypeNode>(SyntaxKind.MappedType);
|
||||
node.readonlyToken = readonlyToken;
|
||||
node.typeParameter = typeParameter;
|
||||
node.nameType = nameType;
|
||||
node.questionToken = questionToken;
|
||||
node.type = type;
|
||||
node.transformFlags = TransformFlags.ContainsTypeScript;
|
||||
@ -1979,12 +2020,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
// @api
|
||||
function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode {
|
||||
function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode {
|
||||
return node.readonlyToken !== readonlyToken
|
||||
|| node.typeParameter !== typeParameter
|
||||
|| node.nameType !== nameType
|
||||
|| node.questionToken !== questionToken
|
||||
|| node.type !== type
|
||||
? update(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
|
||||
? update(createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
||||
@ -206,6 +206,7 @@ namespace ts {
|
||||
case SyntaxKind.MappedType:
|
||||
return visitNode(cbNode, (<MappedTypeNode>node).readonlyToken) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).typeParameter) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).nameType) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).questionToken) ||
|
||||
visitNode(cbNode, (<MappedTypeNode>node).type);
|
||||
case SyntaxKind.LiteralType:
|
||||
@ -424,6 +425,10 @@ namespace ts {
|
||||
return visitNode(cbNode, (<TemplateExpression>node).head) || visitNodes(cbNode, cbNodes, (<TemplateExpression>node).templateSpans);
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return visitNode(cbNode, (<TemplateSpan>node).expression) || visitNode(cbNode, (<TemplateSpan>node).literal);
|
||||
case SyntaxKind.TemplateLiteralType:
|
||||
return visitNode(cbNode, (<TemplateLiteralTypeNode>node).head) || visitNodes(cbNode, cbNodes, (<TemplateLiteralTypeNode>node).templateSpans);
|
||||
case SyntaxKind.TemplateLiteralTypeSpan:
|
||||
return visitNode(cbNode, (<TemplateLiteralTypeSpan>node).type) || visitNode(cbNode, (<TemplateLiteralTypeSpan>node).literal);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return visitNode(cbNode, (<ComputedPropertyName>node).expression);
|
||||
case SyntaxKind.HeritageClause:
|
||||
@ -2584,6 +2589,49 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function parseTemplateType(): TemplateLiteralTypeNode {
|
||||
const pos = getNodePos();
|
||||
return finishNode(
|
||||
factory.createTemplateLiteralType(
|
||||
parseTemplateHead(/*isTaggedTemplate*/ false),
|
||||
parseTemplateTypeSpans()
|
||||
),
|
||||
pos
|
||||
);
|
||||
}
|
||||
|
||||
function parseTemplateTypeSpans() {
|
||||
const pos = getNodePos();
|
||||
const list = [];
|
||||
let node: TemplateLiteralTypeSpan;
|
||||
do {
|
||||
node = parseTemplateTypeSpan();
|
||||
list.push(node);
|
||||
}
|
||||
while (node.literal.kind === SyntaxKind.TemplateMiddle);
|
||||
return createNodeArray(list, pos);
|
||||
}
|
||||
|
||||
function parseTemplateTypeSpan(): TemplateLiteralTypeSpan {
|
||||
const pos = getNodePos();
|
||||
return finishNode(
|
||||
factory.createTemplateLiteralTypeSpan(
|
||||
parseTemplateCasing(),
|
||||
parseType(),
|
||||
parseLiteralOfTemplateSpan(/*isTaggedTemplate*/ false)
|
||||
),
|
||||
pos
|
||||
);
|
||||
}
|
||||
|
||||
function parseTemplateCasing(): TemplateCasing {
|
||||
return parseOptional(SyntaxKind.UppercaseKeyword) ? TemplateCasing.Uppercase :
|
||||
parseOptional(SyntaxKind.LowercaseKeyword) ? TemplateCasing.Lowercase :
|
||||
parseOptional(SyntaxKind.CapitalizeKeyword) ? TemplateCasing.Capitalize :
|
||||
parseOptional(SyntaxKind.UncapitalizeKeyword) ? TemplateCasing.Uncapitalize :
|
||||
TemplateCasing.None;
|
||||
}
|
||||
|
||||
function parseLiteralOfTemplateSpan(isTaggedTemplate: boolean) {
|
||||
if (token() === SyntaxKind.CloseBraceToken) {
|
||||
reScanTemplateToken(isTaggedTemplate);
|
||||
@ -3252,6 +3300,7 @@ namespace ts {
|
||||
}
|
||||
parseExpected(SyntaxKind.OpenBracketToken);
|
||||
const typeParameter = parseMappedTypeParameter();
|
||||
const nameType = parseOptional(SyntaxKind.AsKeyword) ? parseType() : undefined;
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
let questionToken: QuestionToken | PlusToken | MinusToken | undefined;
|
||||
if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) {
|
||||
@ -3263,7 +3312,7 @@ namespace ts {
|
||||
const type = parseTypeAnnotation();
|
||||
parseSemicolon();
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), pos);
|
||||
return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type), pos);
|
||||
}
|
||||
|
||||
function parseTupleElementType() {
|
||||
@ -3444,6 +3493,8 @@ namespace ts {
|
||||
return parseImportType();
|
||||
case SyntaxKind.AssertsKeyword:
|
||||
return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference();
|
||||
case SyntaxKind.TemplateHead:
|
||||
return parseTemplateType();
|
||||
default:
|
||||
return parseTypeReference();
|
||||
}
|
||||
@ -3485,6 +3536,8 @@ namespace ts {
|
||||
case SyntaxKind.InferKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.AssertsKeyword:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
return true;
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return !inStartOfParameter;
|
||||
|
||||
@ -151,6 +151,10 @@ namespace ts {
|
||||
yield: SyntaxKind.YieldKeyword,
|
||||
async: SyntaxKind.AsyncKeyword,
|
||||
await: SyntaxKind.AwaitKeyword,
|
||||
uppercase: SyntaxKind.UppercaseKeyword,
|
||||
lowercase: SyntaxKind.LowercaseKeyword,
|
||||
capitalize: SyntaxKind.CapitalizeKeyword,
|
||||
uncapitalize: SyntaxKind.UncapitalizeKeyword,
|
||||
of: SyntaxKind.OfKeyword,
|
||||
};
|
||||
|
||||
@ -1508,9 +1512,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind {
|
||||
// Reserved words are between 2 and 11 characters long and start with a lowercase letter
|
||||
// Reserved words are between 2 and 12 characters long and start with a lowercase letter
|
||||
const len = tokenValue.length;
|
||||
if (len >= 2 && len <= 11) {
|
||||
if (len >= 2 && len <= 12) {
|
||||
const ch = tokenValue.charCodeAt(0);
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
const keyword = textToKeyword.get(tokenValue);
|
||||
|
||||
@ -186,6 +186,10 @@ namespace ts {
|
||||
FromKeyword,
|
||||
GlobalKeyword,
|
||||
BigIntKeyword,
|
||||
UppercaseKeyword,
|
||||
LowercaseKeyword,
|
||||
CapitalizeKeyword,
|
||||
UncapitalizeKeyword,
|
||||
OfKeyword, // LastKeyword and LastToken and LastContextualKeyword
|
||||
|
||||
// Parse tree nodes
|
||||
@ -230,6 +234,8 @@ namespace ts {
|
||||
MappedType,
|
||||
LiteralType,
|
||||
NamedTupleMember,
|
||||
TemplateLiteralType,
|
||||
TemplateLiteralTypeSpan,
|
||||
ImportType,
|
||||
// Binding patterns
|
||||
ObjectBindingPattern,
|
||||
@ -538,6 +544,7 @@ namespace ts {
|
||||
| SyntaxKind.BigIntKeyword
|
||||
| SyntaxKind.BooleanKeyword
|
||||
| SyntaxKind.BreakKeyword
|
||||
| SyntaxKind.CapitalizeKeyword
|
||||
| SyntaxKind.CaseKeyword
|
||||
| SyntaxKind.CatchKeyword
|
||||
| SyntaxKind.ClassKeyword
|
||||
@ -570,6 +577,7 @@ namespace ts {
|
||||
| SyntaxKind.IsKeyword
|
||||
| SyntaxKind.KeyOfKeyword
|
||||
| SyntaxKind.LetKeyword
|
||||
| SyntaxKind.LowercaseKeyword
|
||||
| SyntaxKind.ModuleKeyword
|
||||
| SyntaxKind.NamespaceKeyword
|
||||
| SyntaxKind.NeverKeyword
|
||||
@ -597,9 +605,11 @@ namespace ts {
|
||||
| SyntaxKind.TryKeyword
|
||||
| SyntaxKind.TypeKeyword
|
||||
| SyntaxKind.TypeOfKeyword
|
||||
| SyntaxKind.UncapitalizeKeyword
|
||||
| SyntaxKind.UndefinedKeyword
|
||||
| SyntaxKind.UniqueKeyword
|
||||
| SyntaxKind.UnknownKeyword
|
||||
| SyntaxKind.UppercaseKeyword
|
||||
| SyntaxKind.VarKeyword
|
||||
| SyntaxKind.VoidKeyword
|
||||
| SyntaxKind.WhileKeyword
|
||||
@ -659,6 +669,8 @@ namespace ts {
|
||||
| SyntaxKind.IndexedAccessType
|
||||
| SyntaxKind.MappedType
|
||||
| SyntaxKind.LiteralType
|
||||
| SyntaxKind.TemplateLiteralType
|
||||
| SyntaxKind.TemplateLiteralTypeSpan
|
||||
| SyntaxKind.ImportType
|
||||
| SyntaxKind.ExpressionWithTypeArguments
|
||||
| SyntaxKind.JSDocTypeExpression
|
||||
@ -1622,6 +1634,7 @@ namespace ts {
|
||||
readonly kind: SyntaxKind.MappedType;
|
||||
readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken;
|
||||
readonly typeParameter: TypeParameterDeclaration;
|
||||
readonly nameType?: TypeNode;
|
||||
readonly questionToken?: QuestionToken | PlusToken | MinusToken;
|
||||
readonly type?: TypeNode;
|
||||
}
|
||||
@ -1641,6 +1654,28 @@ namespace ts {
|
||||
export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral;
|
||||
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
|
||||
|
||||
export interface TemplateLiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.TemplateLiteralType,
|
||||
readonly head: TemplateHead;
|
||||
readonly templateSpans: NodeArray<TemplateLiteralTypeSpan>;
|
||||
}
|
||||
|
||||
export interface TemplateLiteralTypeSpan extends TypeNode {
|
||||
readonly kind: SyntaxKind.TemplateLiteralTypeSpan,
|
||||
readonly parent: TemplateLiteralTypeNode;
|
||||
readonly casing: TemplateCasing;
|
||||
readonly type: TypeNode;
|
||||
readonly literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
|
||||
export const enum TemplateCasing {
|
||||
None,
|
||||
Uppercase,
|
||||
Lowercase,
|
||||
Capitalize,
|
||||
Uncapitalize,
|
||||
}
|
||||
|
||||
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
|
||||
// Consider 'Expression'. Without the brand, 'Expression' is actually no different
|
||||
// (structurally) than 'Node'. Because of this you can pass any Node to a function that
|
||||
@ -2108,21 +2143,21 @@ namespace ts {
|
||||
|
||||
export interface TemplateHead extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateHead;
|
||||
readonly parent: TemplateExpression;
|
||||
readonly parent: TemplateExpression | TemplateLiteralTypeNode;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export interface TemplateMiddle extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateMiddle;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export interface TemplateTail extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateTail;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
@ -4707,7 +4742,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface MappedSymbol extends TransientSymbol {
|
||||
mappedType: MappedType;
|
||||
mapper: TypeMapper;
|
||||
keyType: Type;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -4849,6 +4884,7 @@ namespace ts {
|
||||
Conditional = 1 << 24, // T extends U ? X : Y
|
||||
Substitution = 1 << 25, // Type parameter substitution
|
||||
NonPrimitive = 1 << 26, // intrinsic object type
|
||||
TemplateLiteral = 1 << 27, // Template literal type
|
||||
|
||||
/* @internal */
|
||||
AnyOrUnknown = Any | Unknown,
|
||||
@ -4866,7 +4902,7 @@ namespace ts {
|
||||
Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
|
||||
/* @internal */
|
||||
Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
|
||||
StringLike = String | StringLiteral,
|
||||
StringLike = String | StringLiteral | TemplateLiteral,
|
||||
NumberLike = Number | NumberLiteral | Enum,
|
||||
BigIntLike = BigInt | BigIntLiteral,
|
||||
BooleanLike = Boolean | BooleanLiteral,
|
||||
@ -4879,7 +4915,7 @@ namespace ts {
|
||||
StructuredType = Object | Union | Intersection,
|
||||
TypeVariable = TypeParameter | IndexedAccess,
|
||||
InstantiableNonPrimitive = TypeVariable | Conditional | Substitution,
|
||||
InstantiablePrimitive = Index,
|
||||
InstantiablePrimitive = Index | TemplateLiteral,
|
||||
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
|
||||
StructuredOrInstantiable = StructuredType | Instantiable,
|
||||
/* @internal */
|
||||
@ -4887,7 +4923,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
Simplifiable = IndexedAccess | Conditional,
|
||||
/* @internal */
|
||||
Substructure = Object | Union | Intersection | Index | IndexedAccess | Conditional | Substitution,
|
||||
Substructure = Object | Union | Intersection | Index | IndexedAccess | Conditional | Substitution | TemplateLiteral,
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
|
||||
@ -5194,6 +5230,7 @@ namespace ts {
|
||||
declaration: MappedTypeNode;
|
||||
typeParameter?: TypeParameter;
|
||||
constraintType?: Type;
|
||||
nameType?: Type;
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
resolvedApparentType?: Type;
|
||||
@ -5334,6 +5371,12 @@ namespace ts {
|
||||
combinedMapper?: TypeMapper;
|
||||
}
|
||||
|
||||
export interface TemplateLiteralType extends InstantiableType {
|
||||
texts: readonly string[]; // Always one element longer than casings/types
|
||||
casings: readonly TemplateCasing[]; // Always at least one element
|
||||
types: readonly Type[]; // Always at least one element
|
||||
}
|
||||
|
||||
// Type parameter substitution (TypeFlags.Substitution)
|
||||
// Substitution types are created for type parameters or indexed access types that occur in the
|
||||
// true branch of a conditional type. For example, in 'T extends string ? Foo<T> : Bar<T>', the
|
||||
@ -6715,6 +6758,8 @@ namespace ts {
|
||||
createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
/* @internal */ createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): IndexSignatureDeclaration; // eslint-disable-line @typescript-eslint/unified-signatures
|
||||
updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
createTemplateLiteralTypeSpan(casing: TemplateCasing, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
updateTemplateLiteralTypeSpan(casing: TemplateCasing, node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
|
||||
//
|
||||
// Types
|
||||
@ -6760,10 +6805,12 @@ namespace ts {
|
||||
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
|
||||
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
|
||||
//
|
||||
// Binding Patterns
|
||||
|
||||
@ -565,6 +565,7 @@ namespace ts {
|
||||
return factory.updateMappedTypeNode((<MappedTypeNode>node),
|
||||
nodeVisitor((<MappedTypeNode>node).readonlyToken, tokenVisitor, isToken),
|
||||
nodeVisitor((<MappedTypeNode>node).typeParameter, visitor, isTypeParameterDeclaration),
|
||||
nodeVisitor((<MappedTypeNode>node).nameType, visitor, isTypeNode),
|
||||
nodeVisitor((<MappedTypeNode>node).questionToken, tokenVisitor, isToken),
|
||||
nodeVisitor((<MappedTypeNode>node).type, visitor, isTypeNode));
|
||||
|
||||
|
||||
@ -48,6 +48,6 @@ namespace ts.codefix {
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void {
|
||||
changes.replaceNode(sourceFile, container, factory.createMappedTypeNode(/*readonlyToken*/ undefined,
|
||||
factory.createTypeParameterDeclaration(name, factory.createTypeReferenceNode(constraint)), /*questionToken*/ undefined, typeNode));
|
||||
factory.createTypeParameterDeclaration(name, factory.createTypeReferenceNode(constraint)), /*nameType*/ undefined, /*questionToken*/ undefined, typeNode));
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ namespace ts.codefix {
|
||||
const mappedIntersectionType = factory.createMappedTypeNode(
|
||||
hasEffectiveReadonlyModifier(indexSignature) ? factory.createModifier(SyntaxKind.ReadonlyKeyword) : undefined,
|
||||
mappedTypeParameter,
|
||||
/*nameType*/ undefined,
|
||||
indexSignature.questionToken,
|
||||
indexSignature.type);
|
||||
const intersectionType = factory.createIntersectionTypeNode([
|
||||
|
||||
452
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
452
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
@ -259,190 +259,196 @@ declare namespace ts {
|
||||
FromKeyword = 152,
|
||||
GlobalKeyword = 153,
|
||||
BigIntKeyword = 154,
|
||||
OfKeyword = 155,
|
||||
QualifiedName = 156,
|
||||
ComputedPropertyName = 157,
|
||||
TypeParameter = 158,
|
||||
Parameter = 159,
|
||||
Decorator = 160,
|
||||
PropertySignature = 161,
|
||||
PropertyDeclaration = 162,
|
||||
MethodSignature = 163,
|
||||
MethodDeclaration = 164,
|
||||
Constructor = 165,
|
||||
GetAccessor = 166,
|
||||
SetAccessor = 167,
|
||||
CallSignature = 168,
|
||||
ConstructSignature = 169,
|
||||
IndexSignature = 170,
|
||||
TypePredicate = 171,
|
||||
TypeReference = 172,
|
||||
FunctionType = 173,
|
||||
ConstructorType = 174,
|
||||
TypeQuery = 175,
|
||||
TypeLiteral = 176,
|
||||
ArrayType = 177,
|
||||
TupleType = 178,
|
||||
OptionalType = 179,
|
||||
RestType = 180,
|
||||
UnionType = 181,
|
||||
IntersectionType = 182,
|
||||
ConditionalType = 183,
|
||||
InferType = 184,
|
||||
ParenthesizedType = 185,
|
||||
ThisType = 186,
|
||||
TypeOperator = 187,
|
||||
IndexedAccessType = 188,
|
||||
MappedType = 189,
|
||||
LiteralType = 190,
|
||||
NamedTupleMember = 191,
|
||||
ImportType = 192,
|
||||
ObjectBindingPattern = 193,
|
||||
ArrayBindingPattern = 194,
|
||||
BindingElement = 195,
|
||||
ArrayLiteralExpression = 196,
|
||||
ObjectLiteralExpression = 197,
|
||||
PropertyAccessExpression = 198,
|
||||
ElementAccessExpression = 199,
|
||||
CallExpression = 200,
|
||||
NewExpression = 201,
|
||||
TaggedTemplateExpression = 202,
|
||||
TypeAssertionExpression = 203,
|
||||
ParenthesizedExpression = 204,
|
||||
FunctionExpression = 205,
|
||||
ArrowFunction = 206,
|
||||
DeleteExpression = 207,
|
||||
TypeOfExpression = 208,
|
||||
VoidExpression = 209,
|
||||
AwaitExpression = 210,
|
||||
PrefixUnaryExpression = 211,
|
||||
PostfixUnaryExpression = 212,
|
||||
BinaryExpression = 213,
|
||||
ConditionalExpression = 214,
|
||||
TemplateExpression = 215,
|
||||
YieldExpression = 216,
|
||||
SpreadElement = 217,
|
||||
ClassExpression = 218,
|
||||
OmittedExpression = 219,
|
||||
ExpressionWithTypeArguments = 220,
|
||||
AsExpression = 221,
|
||||
NonNullExpression = 222,
|
||||
MetaProperty = 223,
|
||||
SyntheticExpression = 224,
|
||||
TemplateSpan = 225,
|
||||
SemicolonClassElement = 226,
|
||||
Block = 227,
|
||||
EmptyStatement = 228,
|
||||
VariableStatement = 229,
|
||||
ExpressionStatement = 230,
|
||||
IfStatement = 231,
|
||||
DoStatement = 232,
|
||||
WhileStatement = 233,
|
||||
ForStatement = 234,
|
||||
ForInStatement = 235,
|
||||
ForOfStatement = 236,
|
||||
ContinueStatement = 237,
|
||||
BreakStatement = 238,
|
||||
ReturnStatement = 239,
|
||||
WithStatement = 240,
|
||||
SwitchStatement = 241,
|
||||
LabeledStatement = 242,
|
||||
ThrowStatement = 243,
|
||||
TryStatement = 244,
|
||||
DebuggerStatement = 245,
|
||||
VariableDeclaration = 246,
|
||||
VariableDeclarationList = 247,
|
||||
FunctionDeclaration = 248,
|
||||
ClassDeclaration = 249,
|
||||
InterfaceDeclaration = 250,
|
||||
TypeAliasDeclaration = 251,
|
||||
EnumDeclaration = 252,
|
||||
ModuleDeclaration = 253,
|
||||
ModuleBlock = 254,
|
||||
CaseBlock = 255,
|
||||
NamespaceExportDeclaration = 256,
|
||||
ImportEqualsDeclaration = 257,
|
||||
ImportDeclaration = 258,
|
||||
ImportClause = 259,
|
||||
NamespaceImport = 260,
|
||||
NamedImports = 261,
|
||||
ImportSpecifier = 262,
|
||||
ExportAssignment = 263,
|
||||
ExportDeclaration = 264,
|
||||
NamedExports = 265,
|
||||
NamespaceExport = 266,
|
||||
ExportSpecifier = 267,
|
||||
MissingDeclaration = 268,
|
||||
ExternalModuleReference = 269,
|
||||
JsxElement = 270,
|
||||
JsxSelfClosingElement = 271,
|
||||
JsxOpeningElement = 272,
|
||||
JsxClosingElement = 273,
|
||||
JsxFragment = 274,
|
||||
JsxOpeningFragment = 275,
|
||||
JsxClosingFragment = 276,
|
||||
JsxAttribute = 277,
|
||||
JsxAttributes = 278,
|
||||
JsxSpreadAttribute = 279,
|
||||
JsxExpression = 280,
|
||||
CaseClause = 281,
|
||||
DefaultClause = 282,
|
||||
HeritageClause = 283,
|
||||
CatchClause = 284,
|
||||
PropertyAssignment = 285,
|
||||
ShorthandPropertyAssignment = 286,
|
||||
SpreadAssignment = 287,
|
||||
EnumMember = 288,
|
||||
UnparsedPrologue = 289,
|
||||
UnparsedPrepend = 290,
|
||||
UnparsedText = 291,
|
||||
UnparsedInternalText = 292,
|
||||
UnparsedSyntheticReference = 293,
|
||||
SourceFile = 294,
|
||||
Bundle = 295,
|
||||
UnparsedSource = 296,
|
||||
InputFiles = 297,
|
||||
JSDocTypeExpression = 298,
|
||||
JSDocNameReference = 299,
|
||||
JSDocAllType = 300,
|
||||
JSDocUnknownType = 301,
|
||||
JSDocNullableType = 302,
|
||||
JSDocNonNullableType = 303,
|
||||
JSDocOptionalType = 304,
|
||||
JSDocFunctionType = 305,
|
||||
JSDocVariadicType = 306,
|
||||
JSDocNamepathType = 307,
|
||||
JSDocComment = 308,
|
||||
JSDocTypeLiteral = 309,
|
||||
JSDocSignature = 310,
|
||||
JSDocTag = 311,
|
||||
JSDocAugmentsTag = 312,
|
||||
JSDocImplementsTag = 313,
|
||||
JSDocAuthorTag = 314,
|
||||
JSDocDeprecatedTag = 315,
|
||||
JSDocClassTag = 316,
|
||||
JSDocPublicTag = 317,
|
||||
JSDocPrivateTag = 318,
|
||||
JSDocProtectedTag = 319,
|
||||
JSDocReadonlyTag = 320,
|
||||
JSDocCallbackTag = 321,
|
||||
JSDocEnumTag = 322,
|
||||
JSDocParameterTag = 323,
|
||||
JSDocReturnTag = 324,
|
||||
JSDocThisTag = 325,
|
||||
JSDocTypeTag = 326,
|
||||
JSDocTemplateTag = 327,
|
||||
JSDocTypedefTag = 328,
|
||||
JSDocSeeTag = 329,
|
||||
JSDocPropertyTag = 330,
|
||||
SyntaxList = 331,
|
||||
NotEmittedStatement = 332,
|
||||
PartiallyEmittedExpression = 333,
|
||||
CommaListExpression = 334,
|
||||
MergeDeclarationMarker = 335,
|
||||
EndOfDeclarationMarker = 336,
|
||||
SyntheticReferenceExpression = 337,
|
||||
Count = 338,
|
||||
UppercaseKeyword = 155,
|
||||
LowercaseKeyword = 156,
|
||||
CapitalizeKeyword = 157,
|
||||
UncapitalizeKeyword = 158,
|
||||
OfKeyword = 159,
|
||||
QualifiedName = 160,
|
||||
ComputedPropertyName = 161,
|
||||
TypeParameter = 162,
|
||||
Parameter = 163,
|
||||
Decorator = 164,
|
||||
PropertySignature = 165,
|
||||
PropertyDeclaration = 166,
|
||||
MethodSignature = 167,
|
||||
MethodDeclaration = 168,
|
||||
Constructor = 169,
|
||||
GetAccessor = 170,
|
||||
SetAccessor = 171,
|
||||
CallSignature = 172,
|
||||
ConstructSignature = 173,
|
||||
IndexSignature = 174,
|
||||
TypePredicate = 175,
|
||||
TypeReference = 176,
|
||||
FunctionType = 177,
|
||||
ConstructorType = 178,
|
||||
TypeQuery = 179,
|
||||
TypeLiteral = 180,
|
||||
ArrayType = 181,
|
||||
TupleType = 182,
|
||||
OptionalType = 183,
|
||||
RestType = 184,
|
||||
UnionType = 185,
|
||||
IntersectionType = 186,
|
||||
ConditionalType = 187,
|
||||
InferType = 188,
|
||||
ParenthesizedType = 189,
|
||||
ThisType = 190,
|
||||
TypeOperator = 191,
|
||||
IndexedAccessType = 192,
|
||||
MappedType = 193,
|
||||
LiteralType = 194,
|
||||
NamedTupleMember = 195,
|
||||
TemplateLiteralType = 196,
|
||||
TemplateLiteralTypeSpan = 197,
|
||||
ImportType = 198,
|
||||
ObjectBindingPattern = 199,
|
||||
ArrayBindingPattern = 200,
|
||||
BindingElement = 201,
|
||||
ArrayLiteralExpression = 202,
|
||||
ObjectLiteralExpression = 203,
|
||||
PropertyAccessExpression = 204,
|
||||
ElementAccessExpression = 205,
|
||||
CallExpression = 206,
|
||||
NewExpression = 207,
|
||||
TaggedTemplateExpression = 208,
|
||||
TypeAssertionExpression = 209,
|
||||
ParenthesizedExpression = 210,
|
||||
FunctionExpression = 211,
|
||||
ArrowFunction = 212,
|
||||
DeleteExpression = 213,
|
||||
TypeOfExpression = 214,
|
||||
VoidExpression = 215,
|
||||
AwaitExpression = 216,
|
||||
PrefixUnaryExpression = 217,
|
||||
PostfixUnaryExpression = 218,
|
||||
BinaryExpression = 219,
|
||||
ConditionalExpression = 220,
|
||||
TemplateExpression = 221,
|
||||
YieldExpression = 222,
|
||||
SpreadElement = 223,
|
||||
ClassExpression = 224,
|
||||
OmittedExpression = 225,
|
||||
ExpressionWithTypeArguments = 226,
|
||||
AsExpression = 227,
|
||||
NonNullExpression = 228,
|
||||
MetaProperty = 229,
|
||||
SyntheticExpression = 230,
|
||||
TemplateSpan = 231,
|
||||
SemicolonClassElement = 232,
|
||||
Block = 233,
|
||||
EmptyStatement = 234,
|
||||
VariableStatement = 235,
|
||||
ExpressionStatement = 236,
|
||||
IfStatement = 237,
|
||||
DoStatement = 238,
|
||||
WhileStatement = 239,
|
||||
ForStatement = 240,
|
||||
ForInStatement = 241,
|
||||
ForOfStatement = 242,
|
||||
ContinueStatement = 243,
|
||||
BreakStatement = 244,
|
||||
ReturnStatement = 245,
|
||||
WithStatement = 246,
|
||||
SwitchStatement = 247,
|
||||
LabeledStatement = 248,
|
||||
ThrowStatement = 249,
|
||||
TryStatement = 250,
|
||||
DebuggerStatement = 251,
|
||||
VariableDeclaration = 252,
|
||||
VariableDeclarationList = 253,
|
||||
FunctionDeclaration = 254,
|
||||
ClassDeclaration = 255,
|
||||
InterfaceDeclaration = 256,
|
||||
TypeAliasDeclaration = 257,
|
||||
EnumDeclaration = 258,
|
||||
ModuleDeclaration = 259,
|
||||
ModuleBlock = 260,
|
||||
CaseBlock = 261,
|
||||
NamespaceExportDeclaration = 262,
|
||||
ImportEqualsDeclaration = 263,
|
||||
ImportDeclaration = 264,
|
||||
ImportClause = 265,
|
||||
NamespaceImport = 266,
|
||||
NamedImports = 267,
|
||||
ImportSpecifier = 268,
|
||||
ExportAssignment = 269,
|
||||
ExportDeclaration = 270,
|
||||
NamedExports = 271,
|
||||
NamespaceExport = 272,
|
||||
ExportSpecifier = 273,
|
||||
MissingDeclaration = 274,
|
||||
ExternalModuleReference = 275,
|
||||
JsxElement = 276,
|
||||
JsxSelfClosingElement = 277,
|
||||
JsxOpeningElement = 278,
|
||||
JsxClosingElement = 279,
|
||||
JsxFragment = 280,
|
||||
JsxOpeningFragment = 281,
|
||||
JsxClosingFragment = 282,
|
||||
JsxAttribute = 283,
|
||||
JsxAttributes = 284,
|
||||
JsxSpreadAttribute = 285,
|
||||
JsxExpression = 286,
|
||||
CaseClause = 287,
|
||||
DefaultClause = 288,
|
||||
HeritageClause = 289,
|
||||
CatchClause = 290,
|
||||
PropertyAssignment = 291,
|
||||
ShorthandPropertyAssignment = 292,
|
||||
SpreadAssignment = 293,
|
||||
EnumMember = 294,
|
||||
UnparsedPrologue = 295,
|
||||
UnparsedPrepend = 296,
|
||||
UnparsedText = 297,
|
||||
UnparsedInternalText = 298,
|
||||
UnparsedSyntheticReference = 299,
|
||||
SourceFile = 300,
|
||||
Bundle = 301,
|
||||
UnparsedSource = 302,
|
||||
InputFiles = 303,
|
||||
JSDocTypeExpression = 304,
|
||||
JSDocNameReference = 305,
|
||||
JSDocAllType = 306,
|
||||
JSDocUnknownType = 307,
|
||||
JSDocNullableType = 308,
|
||||
JSDocNonNullableType = 309,
|
||||
JSDocOptionalType = 310,
|
||||
JSDocFunctionType = 311,
|
||||
JSDocVariadicType = 312,
|
||||
JSDocNamepathType = 313,
|
||||
JSDocComment = 314,
|
||||
JSDocTypeLiteral = 315,
|
||||
JSDocSignature = 316,
|
||||
JSDocTag = 317,
|
||||
JSDocAugmentsTag = 318,
|
||||
JSDocImplementsTag = 319,
|
||||
JSDocAuthorTag = 320,
|
||||
JSDocDeprecatedTag = 321,
|
||||
JSDocClassTag = 322,
|
||||
JSDocPublicTag = 323,
|
||||
JSDocPrivateTag = 324,
|
||||
JSDocProtectedTag = 325,
|
||||
JSDocReadonlyTag = 326,
|
||||
JSDocCallbackTag = 327,
|
||||
JSDocEnumTag = 328,
|
||||
JSDocParameterTag = 329,
|
||||
JSDocReturnTag = 330,
|
||||
JSDocThisTag = 331,
|
||||
JSDocTypeTag = 332,
|
||||
JSDocTemplateTag = 333,
|
||||
JSDocTypedefTag = 334,
|
||||
JSDocSeeTag = 335,
|
||||
JSDocPropertyTag = 336,
|
||||
SyntaxList = 337,
|
||||
NotEmittedStatement = 338,
|
||||
PartiallyEmittedExpression = 339,
|
||||
CommaListExpression = 340,
|
||||
MergeDeclarationMarker = 341,
|
||||
EndOfDeclarationMarker = 342,
|
||||
SyntheticReferenceExpression = 343,
|
||||
Count = 344,
|
||||
FirstAssignment = 62,
|
||||
LastAssignment = 77,
|
||||
FirstCompoundAssignment = 63,
|
||||
@ -450,15 +456,15 @@ declare namespace ts {
|
||||
FirstReservedWord = 80,
|
||||
LastReservedWord = 115,
|
||||
FirstKeyword = 80,
|
||||
LastKeyword = 155,
|
||||
LastKeyword = 159,
|
||||
FirstFutureReservedWord = 116,
|
||||
LastFutureReservedWord = 124,
|
||||
FirstTypeNode = 171,
|
||||
LastTypeNode = 192,
|
||||
FirstTypeNode = 175,
|
||||
LastTypeNode = 198,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 77,
|
||||
FirstToken = 0,
|
||||
LastToken = 155,
|
||||
LastToken = 159,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
@ -467,19 +473,19 @@ declare namespace ts {
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 29,
|
||||
LastBinaryOperator = 77,
|
||||
FirstStatement = 229,
|
||||
LastStatement = 245,
|
||||
FirstNode = 156,
|
||||
FirstJSDocNode = 298,
|
||||
LastJSDocNode = 330,
|
||||
FirstJSDocTagNode = 311,
|
||||
LastJSDocTagNode = 330,
|
||||
FirstStatement = 235,
|
||||
LastStatement = 251,
|
||||
FirstNode = 160,
|
||||
FirstJSDocNode = 304,
|
||||
LastJSDocNode = 336,
|
||||
FirstJSDocTagNode = 317,
|
||||
LastJSDocTagNode = 336,
|
||||
}
|
||||
export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia;
|
||||
export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
export type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail;
|
||||
export type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CapitalizeKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.LowercaseKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UncapitalizeKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.UppercaseKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword;
|
||||
export type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.StaticKeyword;
|
||||
export type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword;
|
||||
export type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind;
|
||||
@ -944,6 +950,7 @@ declare namespace ts {
|
||||
readonly kind: SyntaxKind.MappedType;
|
||||
readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken;
|
||||
readonly typeParameter: TypeParameterDeclaration;
|
||||
readonly nameType?: TypeNode;
|
||||
readonly questionToken?: QuestionToken | PlusToken | MinusToken;
|
||||
readonly type?: TypeNode;
|
||||
}
|
||||
@ -956,6 +963,25 @@ declare namespace ts {
|
||||
}
|
||||
export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral;
|
||||
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
|
||||
export interface TemplateLiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.TemplateLiteralType;
|
||||
readonly head: TemplateHead;
|
||||
readonly templateSpans: NodeArray<TemplateLiteralTypeSpan>;
|
||||
}
|
||||
export interface TemplateLiteralTypeSpan extends TypeNode {
|
||||
readonly kind: SyntaxKind.TemplateLiteralTypeSpan;
|
||||
readonly parent: TemplateLiteralTypeNode;
|
||||
readonly casing: TemplateCasing;
|
||||
readonly type: TypeNode;
|
||||
readonly literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
export enum TemplateCasing {
|
||||
None = 0,
|
||||
Uppercase = 1,
|
||||
Lowercase = 2,
|
||||
Capitalize = 3,
|
||||
Uncapitalize = 4
|
||||
}
|
||||
export interface Expression extends Node {
|
||||
_expressionBrand: any;
|
||||
}
|
||||
@ -1144,15 +1170,15 @@ declare namespace ts {
|
||||
export type LiteralToken = NumericLiteral | BigIntLiteral | StringLiteral | JsxText | RegularExpressionLiteral | NoSubstitutionTemplateLiteral;
|
||||
export interface TemplateHead extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateHead;
|
||||
readonly parent: TemplateExpression;
|
||||
readonly parent: TemplateExpression | TemplateLiteralTypeNode;
|
||||
}
|
||||
export interface TemplateMiddle extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateMiddle;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
}
|
||||
export interface TemplateTail extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateTail;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
}
|
||||
export type PseudoLiteralToken = TemplateHead | TemplateMiddle | TemplateTail;
|
||||
export type TemplateLiteralToken = NoSubstitutionTemplateLiteral | PseudoLiteralToken;
|
||||
@ -2460,11 +2486,12 @@ declare namespace ts {
|
||||
Conditional = 16777216,
|
||||
Substitution = 33554432,
|
||||
NonPrimitive = 67108864,
|
||||
TemplateLiteral = 134217728,
|
||||
Literal = 2944,
|
||||
Unit = 109440,
|
||||
StringOrNumberLiteral = 384,
|
||||
PossiblyFalsy = 117724,
|
||||
StringLike = 132,
|
||||
StringLike = 134217860,
|
||||
NumberLike = 296,
|
||||
BigIntLike = 2112,
|
||||
BooleanLike = 528,
|
||||
@ -2475,10 +2502,10 @@ declare namespace ts {
|
||||
StructuredType = 3670016,
|
||||
TypeVariable = 8650752,
|
||||
InstantiableNonPrimitive = 58982400,
|
||||
InstantiablePrimitive = 4194304,
|
||||
Instantiable = 63176704,
|
||||
StructuredOrInstantiable = 66846720,
|
||||
Narrowable = 133970943,
|
||||
InstantiablePrimitive = 138412032,
|
||||
Instantiable = 197394432,
|
||||
StructuredOrInstantiable = 201064448,
|
||||
Narrowable = 268188671,
|
||||
}
|
||||
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
|
||||
export interface Type {
|
||||
@ -2629,6 +2656,11 @@ declare namespace ts {
|
||||
resolvedTrueType: Type;
|
||||
resolvedFalseType: Type;
|
||||
}
|
||||
export interface TemplateLiteralType extends InstantiableType {
|
||||
texts: readonly string[];
|
||||
casings: readonly TemplateCasing[];
|
||||
types: readonly Type[];
|
||||
}
|
||||
export interface SubstitutionType extends InstantiableType {
|
||||
baseType: Type;
|
||||
substitute: Type;
|
||||
@ -3186,6 +3218,8 @@ declare namespace ts {
|
||||
updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructSignatureDeclaration;
|
||||
createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
createTemplateLiteralTypeSpan(casing: TemplateCasing, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
updateTemplateLiteralTypeSpan(casing: TemplateCasing, node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
createKeywordTypeNode<TKind extends KeywordTypeSyntaxKind>(kind: TKind): KeywordTypeNode<TKind>;
|
||||
createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode;
|
||||
updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode;
|
||||
@ -3226,10 +3260,12 @@ declare namespace ts {
|
||||
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
|
||||
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern;
|
||||
updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern;
|
||||
createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern;
|
||||
@ -10148,9 +10184,9 @@ declare namespace ts {
|
||||
/** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode;
|
||||
/** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
/** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
/** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const createLiteralTypeNode: (literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode;
|
||||
/** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */
|
||||
|
||||
452
tests/baselines/reference/api/typescript.d.ts
vendored
452
tests/baselines/reference/api/typescript.d.ts
vendored
@ -259,190 +259,196 @@ declare namespace ts {
|
||||
FromKeyword = 152,
|
||||
GlobalKeyword = 153,
|
||||
BigIntKeyword = 154,
|
||||
OfKeyword = 155,
|
||||
QualifiedName = 156,
|
||||
ComputedPropertyName = 157,
|
||||
TypeParameter = 158,
|
||||
Parameter = 159,
|
||||
Decorator = 160,
|
||||
PropertySignature = 161,
|
||||
PropertyDeclaration = 162,
|
||||
MethodSignature = 163,
|
||||
MethodDeclaration = 164,
|
||||
Constructor = 165,
|
||||
GetAccessor = 166,
|
||||
SetAccessor = 167,
|
||||
CallSignature = 168,
|
||||
ConstructSignature = 169,
|
||||
IndexSignature = 170,
|
||||
TypePredicate = 171,
|
||||
TypeReference = 172,
|
||||
FunctionType = 173,
|
||||
ConstructorType = 174,
|
||||
TypeQuery = 175,
|
||||
TypeLiteral = 176,
|
||||
ArrayType = 177,
|
||||
TupleType = 178,
|
||||
OptionalType = 179,
|
||||
RestType = 180,
|
||||
UnionType = 181,
|
||||
IntersectionType = 182,
|
||||
ConditionalType = 183,
|
||||
InferType = 184,
|
||||
ParenthesizedType = 185,
|
||||
ThisType = 186,
|
||||
TypeOperator = 187,
|
||||
IndexedAccessType = 188,
|
||||
MappedType = 189,
|
||||
LiteralType = 190,
|
||||
NamedTupleMember = 191,
|
||||
ImportType = 192,
|
||||
ObjectBindingPattern = 193,
|
||||
ArrayBindingPattern = 194,
|
||||
BindingElement = 195,
|
||||
ArrayLiteralExpression = 196,
|
||||
ObjectLiteralExpression = 197,
|
||||
PropertyAccessExpression = 198,
|
||||
ElementAccessExpression = 199,
|
||||
CallExpression = 200,
|
||||
NewExpression = 201,
|
||||
TaggedTemplateExpression = 202,
|
||||
TypeAssertionExpression = 203,
|
||||
ParenthesizedExpression = 204,
|
||||
FunctionExpression = 205,
|
||||
ArrowFunction = 206,
|
||||
DeleteExpression = 207,
|
||||
TypeOfExpression = 208,
|
||||
VoidExpression = 209,
|
||||
AwaitExpression = 210,
|
||||
PrefixUnaryExpression = 211,
|
||||
PostfixUnaryExpression = 212,
|
||||
BinaryExpression = 213,
|
||||
ConditionalExpression = 214,
|
||||
TemplateExpression = 215,
|
||||
YieldExpression = 216,
|
||||
SpreadElement = 217,
|
||||
ClassExpression = 218,
|
||||
OmittedExpression = 219,
|
||||
ExpressionWithTypeArguments = 220,
|
||||
AsExpression = 221,
|
||||
NonNullExpression = 222,
|
||||
MetaProperty = 223,
|
||||
SyntheticExpression = 224,
|
||||
TemplateSpan = 225,
|
||||
SemicolonClassElement = 226,
|
||||
Block = 227,
|
||||
EmptyStatement = 228,
|
||||
VariableStatement = 229,
|
||||
ExpressionStatement = 230,
|
||||
IfStatement = 231,
|
||||
DoStatement = 232,
|
||||
WhileStatement = 233,
|
||||
ForStatement = 234,
|
||||
ForInStatement = 235,
|
||||
ForOfStatement = 236,
|
||||
ContinueStatement = 237,
|
||||
BreakStatement = 238,
|
||||
ReturnStatement = 239,
|
||||
WithStatement = 240,
|
||||
SwitchStatement = 241,
|
||||
LabeledStatement = 242,
|
||||
ThrowStatement = 243,
|
||||
TryStatement = 244,
|
||||
DebuggerStatement = 245,
|
||||
VariableDeclaration = 246,
|
||||
VariableDeclarationList = 247,
|
||||
FunctionDeclaration = 248,
|
||||
ClassDeclaration = 249,
|
||||
InterfaceDeclaration = 250,
|
||||
TypeAliasDeclaration = 251,
|
||||
EnumDeclaration = 252,
|
||||
ModuleDeclaration = 253,
|
||||
ModuleBlock = 254,
|
||||
CaseBlock = 255,
|
||||
NamespaceExportDeclaration = 256,
|
||||
ImportEqualsDeclaration = 257,
|
||||
ImportDeclaration = 258,
|
||||
ImportClause = 259,
|
||||
NamespaceImport = 260,
|
||||
NamedImports = 261,
|
||||
ImportSpecifier = 262,
|
||||
ExportAssignment = 263,
|
||||
ExportDeclaration = 264,
|
||||
NamedExports = 265,
|
||||
NamespaceExport = 266,
|
||||
ExportSpecifier = 267,
|
||||
MissingDeclaration = 268,
|
||||
ExternalModuleReference = 269,
|
||||
JsxElement = 270,
|
||||
JsxSelfClosingElement = 271,
|
||||
JsxOpeningElement = 272,
|
||||
JsxClosingElement = 273,
|
||||
JsxFragment = 274,
|
||||
JsxOpeningFragment = 275,
|
||||
JsxClosingFragment = 276,
|
||||
JsxAttribute = 277,
|
||||
JsxAttributes = 278,
|
||||
JsxSpreadAttribute = 279,
|
||||
JsxExpression = 280,
|
||||
CaseClause = 281,
|
||||
DefaultClause = 282,
|
||||
HeritageClause = 283,
|
||||
CatchClause = 284,
|
||||
PropertyAssignment = 285,
|
||||
ShorthandPropertyAssignment = 286,
|
||||
SpreadAssignment = 287,
|
||||
EnumMember = 288,
|
||||
UnparsedPrologue = 289,
|
||||
UnparsedPrepend = 290,
|
||||
UnparsedText = 291,
|
||||
UnparsedInternalText = 292,
|
||||
UnparsedSyntheticReference = 293,
|
||||
SourceFile = 294,
|
||||
Bundle = 295,
|
||||
UnparsedSource = 296,
|
||||
InputFiles = 297,
|
||||
JSDocTypeExpression = 298,
|
||||
JSDocNameReference = 299,
|
||||
JSDocAllType = 300,
|
||||
JSDocUnknownType = 301,
|
||||
JSDocNullableType = 302,
|
||||
JSDocNonNullableType = 303,
|
||||
JSDocOptionalType = 304,
|
||||
JSDocFunctionType = 305,
|
||||
JSDocVariadicType = 306,
|
||||
JSDocNamepathType = 307,
|
||||
JSDocComment = 308,
|
||||
JSDocTypeLiteral = 309,
|
||||
JSDocSignature = 310,
|
||||
JSDocTag = 311,
|
||||
JSDocAugmentsTag = 312,
|
||||
JSDocImplementsTag = 313,
|
||||
JSDocAuthorTag = 314,
|
||||
JSDocDeprecatedTag = 315,
|
||||
JSDocClassTag = 316,
|
||||
JSDocPublicTag = 317,
|
||||
JSDocPrivateTag = 318,
|
||||
JSDocProtectedTag = 319,
|
||||
JSDocReadonlyTag = 320,
|
||||
JSDocCallbackTag = 321,
|
||||
JSDocEnumTag = 322,
|
||||
JSDocParameterTag = 323,
|
||||
JSDocReturnTag = 324,
|
||||
JSDocThisTag = 325,
|
||||
JSDocTypeTag = 326,
|
||||
JSDocTemplateTag = 327,
|
||||
JSDocTypedefTag = 328,
|
||||
JSDocSeeTag = 329,
|
||||
JSDocPropertyTag = 330,
|
||||
SyntaxList = 331,
|
||||
NotEmittedStatement = 332,
|
||||
PartiallyEmittedExpression = 333,
|
||||
CommaListExpression = 334,
|
||||
MergeDeclarationMarker = 335,
|
||||
EndOfDeclarationMarker = 336,
|
||||
SyntheticReferenceExpression = 337,
|
||||
Count = 338,
|
||||
UppercaseKeyword = 155,
|
||||
LowercaseKeyword = 156,
|
||||
CapitalizeKeyword = 157,
|
||||
UncapitalizeKeyword = 158,
|
||||
OfKeyword = 159,
|
||||
QualifiedName = 160,
|
||||
ComputedPropertyName = 161,
|
||||
TypeParameter = 162,
|
||||
Parameter = 163,
|
||||
Decorator = 164,
|
||||
PropertySignature = 165,
|
||||
PropertyDeclaration = 166,
|
||||
MethodSignature = 167,
|
||||
MethodDeclaration = 168,
|
||||
Constructor = 169,
|
||||
GetAccessor = 170,
|
||||
SetAccessor = 171,
|
||||
CallSignature = 172,
|
||||
ConstructSignature = 173,
|
||||
IndexSignature = 174,
|
||||
TypePredicate = 175,
|
||||
TypeReference = 176,
|
||||
FunctionType = 177,
|
||||
ConstructorType = 178,
|
||||
TypeQuery = 179,
|
||||
TypeLiteral = 180,
|
||||
ArrayType = 181,
|
||||
TupleType = 182,
|
||||
OptionalType = 183,
|
||||
RestType = 184,
|
||||
UnionType = 185,
|
||||
IntersectionType = 186,
|
||||
ConditionalType = 187,
|
||||
InferType = 188,
|
||||
ParenthesizedType = 189,
|
||||
ThisType = 190,
|
||||
TypeOperator = 191,
|
||||
IndexedAccessType = 192,
|
||||
MappedType = 193,
|
||||
LiteralType = 194,
|
||||
NamedTupleMember = 195,
|
||||
TemplateLiteralType = 196,
|
||||
TemplateLiteralTypeSpan = 197,
|
||||
ImportType = 198,
|
||||
ObjectBindingPattern = 199,
|
||||
ArrayBindingPattern = 200,
|
||||
BindingElement = 201,
|
||||
ArrayLiteralExpression = 202,
|
||||
ObjectLiteralExpression = 203,
|
||||
PropertyAccessExpression = 204,
|
||||
ElementAccessExpression = 205,
|
||||
CallExpression = 206,
|
||||
NewExpression = 207,
|
||||
TaggedTemplateExpression = 208,
|
||||
TypeAssertionExpression = 209,
|
||||
ParenthesizedExpression = 210,
|
||||
FunctionExpression = 211,
|
||||
ArrowFunction = 212,
|
||||
DeleteExpression = 213,
|
||||
TypeOfExpression = 214,
|
||||
VoidExpression = 215,
|
||||
AwaitExpression = 216,
|
||||
PrefixUnaryExpression = 217,
|
||||
PostfixUnaryExpression = 218,
|
||||
BinaryExpression = 219,
|
||||
ConditionalExpression = 220,
|
||||
TemplateExpression = 221,
|
||||
YieldExpression = 222,
|
||||
SpreadElement = 223,
|
||||
ClassExpression = 224,
|
||||
OmittedExpression = 225,
|
||||
ExpressionWithTypeArguments = 226,
|
||||
AsExpression = 227,
|
||||
NonNullExpression = 228,
|
||||
MetaProperty = 229,
|
||||
SyntheticExpression = 230,
|
||||
TemplateSpan = 231,
|
||||
SemicolonClassElement = 232,
|
||||
Block = 233,
|
||||
EmptyStatement = 234,
|
||||
VariableStatement = 235,
|
||||
ExpressionStatement = 236,
|
||||
IfStatement = 237,
|
||||
DoStatement = 238,
|
||||
WhileStatement = 239,
|
||||
ForStatement = 240,
|
||||
ForInStatement = 241,
|
||||
ForOfStatement = 242,
|
||||
ContinueStatement = 243,
|
||||
BreakStatement = 244,
|
||||
ReturnStatement = 245,
|
||||
WithStatement = 246,
|
||||
SwitchStatement = 247,
|
||||
LabeledStatement = 248,
|
||||
ThrowStatement = 249,
|
||||
TryStatement = 250,
|
||||
DebuggerStatement = 251,
|
||||
VariableDeclaration = 252,
|
||||
VariableDeclarationList = 253,
|
||||
FunctionDeclaration = 254,
|
||||
ClassDeclaration = 255,
|
||||
InterfaceDeclaration = 256,
|
||||
TypeAliasDeclaration = 257,
|
||||
EnumDeclaration = 258,
|
||||
ModuleDeclaration = 259,
|
||||
ModuleBlock = 260,
|
||||
CaseBlock = 261,
|
||||
NamespaceExportDeclaration = 262,
|
||||
ImportEqualsDeclaration = 263,
|
||||
ImportDeclaration = 264,
|
||||
ImportClause = 265,
|
||||
NamespaceImport = 266,
|
||||
NamedImports = 267,
|
||||
ImportSpecifier = 268,
|
||||
ExportAssignment = 269,
|
||||
ExportDeclaration = 270,
|
||||
NamedExports = 271,
|
||||
NamespaceExport = 272,
|
||||
ExportSpecifier = 273,
|
||||
MissingDeclaration = 274,
|
||||
ExternalModuleReference = 275,
|
||||
JsxElement = 276,
|
||||
JsxSelfClosingElement = 277,
|
||||
JsxOpeningElement = 278,
|
||||
JsxClosingElement = 279,
|
||||
JsxFragment = 280,
|
||||
JsxOpeningFragment = 281,
|
||||
JsxClosingFragment = 282,
|
||||
JsxAttribute = 283,
|
||||
JsxAttributes = 284,
|
||||
JsxSpreadAttribute = 285,
|
||||
JsxExpression = 286,
|
||||
CaseClause = 287,
|
||||
DefaultClause = 288,
|
||||
HeritageClause = 289,
|
||||
CatchClause = 290,
|
||||
PropertyAssignment = 291,
|
||||
ShorthandPropertyAssignment = 292,
|
||||
SpreadAssignment = 293,
|
||||
EnumMember = 294,
|
||||
UnparsedPrologue = 295,
|
||||
UnparsedPrepend = 296,
|
||||
UnparsedText = 297,
|
||||
UnparsedInternalText = 298,
|
||||
UnparsedSyntheticReference = 299,
|
||||
SourceFile = 300,
|
||||
Bundle = 301,
|
||||
UnparsedSource = 302,
|
||||
InputFiles = 303,
|
||||
JSDocTypeExpression = 304,
|
||||
JSDocNameReference = 305,
|
||||
JSDocAllType = 306,
|
||||
JSDocUnknownType = 307,
|
||||
JSDocNullableType = 308,
|
||||
JSDocNonNullableType = 309,
|
||||
JSDocOptionalType = 310,
|
||||
JSDocFunctionType = 311,
|
||||
JSDocVariadicType = 312,
|
||||
JSDocNamepathType = 313,
|
||||
JSDocComment = 314,
|
||||
JSDocTypeLiteral = 315,
|
||||
JSDocSignature = 316,
|
||||
JSDocTag = 317,
|
||||
JSDocAugmentsTag = 318,
|
||||
JSDocImplementsTag = 319,
|
||||
JSDocAuthorTag = 320,
|
||||
JSDocDeprecatedTag = 321,
|
||||
JSDocClassTag = 322,
|
||||
JSDocPublicTag = 323,
|
||||
JSDocPrivateTag = 324,
|
||||
JSDocProtectedTag = 325,
|
||||
JSDocReadonlyTag = 326,
|
||||
JSDocCallbackTag = 327,
|
||||
JSDocEnumTag = 328,
|
||||
JSDocParameterTag = 329,
|
||||
JSDocReturnTag = 330,
|
||||
JSDocThisTag = 331,
|
||||
JSDocTypeTag = 332,
|
||||
JSDocTemplateTag = 333,
|
||||
JSDocTypedefTag = 334,
|
||||
JSDocSeeTag = 335,
|
||||
JSDocPropertyTag = 336,
|
||||
SyntaxList = 337,
|
||||
NotEmittedStatement = 338,
|
||||
PartiallyEmittedExpression = 339,
|
||||
CommaListExpression = 340,
|
||||
MergeDeclarationMarker = 341,
|
||||
EndOfDeclarationMarker = 342,
|
||||
SyntheticReferenceExpression = 343,
|
||||
Count = 344,
|
||||
FirstAssignment = 62,
|
||||
LastAssignment = 77,
|
||||
FirstCompoundAssignment = 63,
|
||||
@ -450,15 +456,15 @@ declare namespace ts {
|
||||
FirstReservedWord = 80,
|
||||
LastReservedWord = 115,
|
||||
FirstKeyword = 80,
|
||||
LastKeyword = 155,
|
||||
LastKeyword = 159,
|
||||
FirstFutureReservedWord = 116,
|
||||
LastFutureReservedWord = 124,
|
||||
FirstTypeNode = 171,
|
||||
LastTypeNode = 192,
|
||||
FirstTypeNode = 175,
|
||||
LastTypeNode = 198,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 77,
|
||||
FirstToken = 0,
|
||||
LastToken = 155,
|
||||
LastToken = 159,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
@ -467,19 +473,19 @@ declare namespace ts {
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 29,
|
||||
LastBinaryOperator = 77,
|
||||
FirstStatement = 229,
|
||||
LastStatement = 245,
|
||||
FirstNode = 156,
|
||||
FirstJSDocNode = 298,
|
||||
LastJSDocNode = 330,
|
||||
FirstJSDocTagNode = 311,
|
||||
LastJSDocTagNode = 330,
|
||||
FirstStatement = 235,
|
||||
LastStatement = 251,
|
||||
FirstNode = 160,
|
||||
FirstJSDocNode = 304,
|
||||
LastJSDocNode = 336,
|
||||
FirstJSDocTagNode = 317,
|
||||
LastJSDocTagNode = 336,
|
||||
}
|
||||
export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia;
|
||||
export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
export type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail;
|
||||
export type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CapitalizeKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.LowercaseKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UncapitalizeKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.UppercaseKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword;
|
||||
export type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.StaticKeyword;
|
||||
export type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword;
|
||||
export type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind;
|
||||
@ -944,6 +950,7 @@ declare namespace ts {
|
||||
readonly kind: SyntaxKind.MappedType;
|
||||
readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken;
|
||||
readonly typeParameter: TypeParameterDeclaration;
|
||||
readonly nameType?: TypeNode;
|
||||
readonly questionToken?: QuestionToken | PlusToken | MinusToken;
|
||||
readonly type?: TypeNode;
|
||||
}
|
||||
@ -956,6 +963,25 @@ declare namespace ts {
|
||||
}
|
||||
export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral;
|
||||
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
|
||||
export interface TemplateLiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.TemplateLiteralType;
|
||||
readonly head: TemplateHead;
|
||||
readonly templateSpans: NodeArray<TemplateLiteralTypeSpan>;
|
||||
}
|
||||
export interface TemplateLiteralTypeSpan extends TypeNode {
|
||||
readonly kind: SyntaxKind.TemplateLiteralTypeSpan;
|
||||
readonly parent: TemplateLiteralTypeNode;
|
||||
readonly casing: TemplateCasing;
|
||||
readonly type: TypeNode;
|
||||
readonly literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
export enum TemplateCasing {
|
||||
None = 0,
|
||||
Uppercase = 1,
|
||||
Lowercase = 2,
|
||||
Capitalize = 3,
|
||||
Uncapitalize = 4
|
||||
}
|
||||
export interface Expression extends Node {
|
||||
_expressionBrand: any;
|
||||
}
|
||||
@ -1144,15 +1170,15 @@ declare namespace ts {
|
||||
export type LiteralToken = NumericLiteral | BigIntLiteral | StringLiteral | JsxText | RegularExpressionLiteral | NoSubstitutionTemplateLiteral;
|
||||
export interface TemplateHead extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateHead;
|
||||
readonly parent: TemplateExpression;
|
||||
readonly parent: TemplateExpression | TemplateLiteralTypeNode;
|
||||
}
|
||||
export interface TemplateMiddle extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateMiddle;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
}
|
||||
export interface TemplateTail extends TemplateLiteralLikeNode {
|
||||
readonly kind: SyntaxKind.TemplateTail;
|
||||
readonly parent: TemplateSpan;
|
||||
readonly parent: TemplateSpan | TemplateLiteralTypeSpan;
|
||||
}
|
||||
export type PseudoLiteralToken = TemplateHead | TemplateMiddle | TemplateTail;
|
||||
export type TemplateLiteralToken = NoSubstitutionTemplateLiteral | PseudoLiteralToken;
|
||||
@ -2460,11 +2486,12 @@ declare namespace ts {
|
||||
Conditional = 16777216,
|
||||
Substitution = 33554432,
|
||||
NonPrimitive = 67108864,
|
||||
TemplateLiteral = 134217728,
|
||||
Literal = 2944,
|
||||
Unit = 109440,
|
||||
StringOrNumberLiteral = 384,
|
||||
PossiblyFalsy = 117724,
|
||||
StringLike = 132,
|
||||
StringLike = 134217860,
|
||||
NumberLike = 296,
|
||||
BigIntLike = 2112,
|
||||
BooleanLike = 528,
|
||||
@ -2475,10 +2502,10 @@ declare namespace ts {
|
||||
StructuredType = 3670016,
|
||||
TypeVariable = 8650752,
|
||||
InstantiableNonPrimitive = 58982400,
|
||||
InstantiablePrimitive = 4194304,
|
||||
Instantiable = 63176704,
|
||||
StructuredOrInstantiable = 66846720,
|
||||
Narrowable = 133970943,
|
||||
InstantiablePrimitive = 138412032,
|
||||
Instantiable = 197394432,
|
||||
StructuredOrInstantiable = 201064448,
|
||||
Narrowable = 268188671,
|
||||
}
|
||||
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
|
||||
export interface Type {
|
||||
@ -2629,6 +2656,11 @@ declare namespace ts {
|
||||
resolvedTrueType: Type;
|
||||
resolvedFalseType: Type;
|
||||
}
|
||||
export interface TemplateLiteralType extends InstantiableType {
|
||||
texts: readonly string[];
|
||||
casings: readonly TemplateCasing[];
|
||||
types: readonly Type[];
|
||||
}
|
||||
export interface SubstitutionType extends InstantiableType {
|
||||
baseType: Type;
|
||||
substitute: Type;
|
||||
@ -3186,6 +3218,8 @@ declare namespace ts {
|
||||
updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructSignatureDeclaration;
|
||||
createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
createTemplateLiteralTypeSpan(casing: TemplateCasing, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
updateTemplateLiteralTypeSpan(casing: TemplateCasing, node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail): TemplateLiteralTypeSpan;
|
||||
createKeywordTypeNode<TKind extends KeywordTypeSyntaxKind>(kind: TKind): KeywordTypeNode<TKind>;
|
||||
createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode;
|
||||
updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode;
|
||||
@ -3226,10 +3260,12 @@ declare namespace ts {
|
||||
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
|
||||
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
|
||||
createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode;
|
||||
createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode;
|
||||
createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern;
|
||||
updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern;
|
||||
createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern;
|
||||
@ -6528,9 +6564,9 @@ declare namespace ts {
|
||||
/** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode;
|
||||
/** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
/** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode;
|
||||
/** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */
|
||||
const createLiteralTypeNode: (literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode;
|
||||
/** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */
|
||||
|
||||
@ -15,7 +15,7 @@ declare function Func<Values = object, ExtraProps = {}>(
|
||||
>Func : <Values = object, ExtraProps = {}>(x: (string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>)) => void
|
||||
|
||||
x: (string extends "validate" | "initialValues" | keyof ExtraProps
|
||||
>x : string extends keyof ExtraProps | "validate" | "initialValues" ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, Exclude<keyof ExtraProps, "validateOnChange"> | "validate" | "initialValues"> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>
|
||||
>x : string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>
|
||||
|
||||
? Readonly<FormikConfig<Values> & ExtraProps>
|
||||
: Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">>
|
||||
@ -24,7 +24,7 @@ declare function Func<Values = object, ExtraProps = {}>(
|
||||
|
||||
Func({
|
||||
>Func({ initialValues: { foo: "" }, validate: props => { props.foo; }}) : void
|
||||
>Func : <Values = object, ExtraProps = {}>(x: string extends keyof ExtraProps | "validate" | "initialValues" ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, Exclude<keyof ExtraProps, "validateOnChange"> | "validate" | "initialValues"> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>) => void
|
||||
>Func : <Values = object, ExtraProps = {}>(x: string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>) => void
|
||||
>{ initialValues: { foo: "" }, validate: props => { props.foo; }} : { initialValues: { foo: string; }; validate: (props: { foo: string; }) => void; }
|
||||
|
||||
initialValues: {
|
||||
|
||||
@ -125,7 +125,7 @@ type NAME = "name";
|
||||
>NAME : "name"
|
||||
|
||||
type WIDTH_OR_HEIGHT = "width" | "height";
|
||||
>WIDTH_OR_HEIGHT : "width" | "height"
|
||||
>WIDTH_OR_HEIGHT : WIDTH_OR_HEIGHT
|
||||
|
||||
type Q10 = Shape["name"]; // string
|
||||
>Q10 : string
|
||||
@ -225,7 +225,7 @@ function f10(shape: Shape) {
|
||||
>getProperty(shape, cond ? "width" : "height") : number
|
||||
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
|
||||
>shape : Shape
|
||||
>cond ? "width" : "height" : "width" | "height"
|
||||
>cond ? "width" : "height" : WIDTH_OR_HEIGHT
|
||||
>cond : boolean
|
||||
>"width" : "width"
|
||||
>"height" : "height"
|
||||
@ -251,7 +251,7 @@ function f10(shape: Shape) {
|
||||
>setProperty(shape, cond ? "width" : "height", 10) : void
|
||||
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
|
||||
>shape : Shape
|
||||
>cond ? "width" : "height" : "width" | "height"
|
||||
>cond ? "width" : "height" : WIDTH_OR_HEIGHT
|
||||
>cond : boolean
|
||||
>"width" : "width"
|
||||
>"height" : "height"
|
||||
@ -391,7 +391,7 @@ function f20(component: Component<Shape>) {
|
||||
>component.getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
|
||||
>component : Component<Shape>
|
||||
>getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
|
||||
>cond ? "width" : "height" : "width" | "height"
|
||||
>cond ? "width" : "height" : WIDTH_OR_HEIGHT
|
||||
>cond : boolean
|
||||
>"width" : "width"
|
||||
>"height" : "height"
|
||||
@ -420,7 +420,7 @@ function f20(component: Component<Shape>) {
|
||||
>component.setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
|
||||
>component : Component<Shape>
|
||||
>setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
|
||||
>cond ? "width" : "height" : "width" | "height"
|
||||
>cond ? "width" : "height" : WIDTH_OR_HEIGHT
|
||||
>cond : boolean
|
||||
>"width" : "width"
|
||||
>"height" : "height"
|
||||
@ -507,7 +507,7 @@ function f31<K extends keyof Shape>(key: K) {
|
||||
}
|
||||
|
||||
function f32<K extends "width" | "height">(key: K) {
|
||||
>f32 : <K extends "width" | "height">(key: K) => Shape[K]
|
||||
>f32 : <K extends WIDTH_OR_HEIGHT>(key: K) => Shape[K]
|
||||
>key : K
|
||||
|
||||
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
|
||||
|
||||
@ -6,7 +6,7 @@ declare const barProp: unique symbol;
|
||||
>barProp : unique symbol
|
||||
|
||||
type BothProps = typeof fooProp | typeof barProp;
|
||||
>BothProps : unique symbol | unique symbol
|
||||
>BothProps : BothProps
|
||||
>fooProp : unique symbol
|
||||
>barProp : unique symbol
|
||||
|
||||
|
||||
84
tests/baselines/reference/mappedTypeAsClauses.js
Normal file
84
tests/baselines/reference/mappedTypeAsClauses.js
Normal file
@ -0,0 +1,84 @@
|
||||
//// [mappedTypeAsClauses.ts]
|
||||
// Mapped type 'as N' clauses
|
||||
|
||||
type Getters<T> = { [P in keyof T & string as `get${capitalize P}`]: () => T[P] };
|
||||
type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>;
|
||||
|
||||
// Mapped type with 'as N' clause has no constraint on 'in T' clause
|
||||
|
||||
type PropDef<K extends keyof any, T> = { name: K, type: T };
|
||||
|
||||
type TypeFromDefs<T extends PropDef<keyof any, any>> = { [P in T as P['name']]: P['type'] };
|
||||
|
||||
type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>;
|
||||
|
||||
// No array or tuple type mapping when 'as N' clause present
|
||||
|
||||
type TA1 = Getters<string[]>;
|
||||
type TA2 = Getters<[number, boolean]>;
|
||||
|
||||
// Filtering using 'as N' clause
|
||||
|
||||
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
|
||||
type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>;
|
||||
|
||||
// Mapping to multiple names using 'as N' clause
|
||||
|
||||
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
|
||||
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
|
||||
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
|
||||
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
|
||||
|
||||
|
||||
//// [mappedTypeAsClauses.js]
|
||||
"use strict";
|
||||
// Mapped type 'as N' clauses
|
||||
|
||||
|
||||
//// [mappedTypeAsClauses.d.ts]
|
||||
declare type Getters<T> = {
|
||||
[P in keyof T & string as `get${capitalize P}`]: () => T[P];
|
||||
};
|
||||
declare type TG1 = Getters<{
|
||||
foo: string;
|
||||
bar: number;
|
||||
baz: {
|
||||
z: boolean;
|
||||
};
|
||||
}>;
|
||||
declare type PropDef<K extends keyof any, T> = {
|
||||
name: K;
|
||||
type: T;
|
||||
};
|
||||
declare type TypeFromDefs<T extends PropDef<keyof any, any>> = {
|
||||
[P in T as P['name']]: P['type'];
|
||||
};
|
||||
declare type TP1 = TypeFromDefs<{
|
||||
name: 'a';
|
||||
type: string;
|
||||
} | {
|
||||
name: 'b';
|
||||
type: number;
|
||||
} | {
|
||||
name: 'a';
|
||||
type: boolean;
|
||||
}>;
|
||||
declare type TA1 = Getters<string[]>;
|
||||
declare type TA2 = Getters<[number, boolean]>;
|
||||
declare type Methods<T> = {
|
||||
[P in keyof T as T[P] extends Function ? P : never]: T[P];
|
||||
};
|
||||
declare type TM1 = Methods<{
|
||||
foo(): number;
|
||||
bar(x: string): boolean;
|
||||
baz: string | number;
|
||||
}>;
|
||||
declare type DoubleProp<T> = {
|
||||
[P in keyof T & string as `${P}1` | `${P}2`]: T[P];
|
||||
};
|
||||
declare type TD1 = DoubleProp<{
|
||||
a: string;
|
||||
b: number;
|
||||
}>;
|
||||
declare type TD2 = keyof TD1;
|
||||
declare type TD3<U> = keyof DoubleProp<U>;
|
||||
110
tests/baselines/reference/mappedTypeAsClauses.symbols
Normal file
110
tests/baselines/reference/mappedTypeAsClauses.symbols
Normal file
@ -0,0 +1,110 @@
|
||||
=== tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts ===
|
||||
// Mapped type 'as N' clauses
|
||||
|
||||
type Getters<T> = { [P in keyof T & string as `get${capitalize P}`]: () => T[P] };
|
||||
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
|
||||
|
||||
type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>;
|
||||
>TG1 : Symbol(TG1, Decl(mappedTypeAsClauses.ts, 2, 82))
|
||||
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 3, 20))
|
||||
>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 3, 33))
|
||||
>baz : Symbol(baz, Decl(mappedTypeAsClauses.ts, 3, 46))
|
||||
>z : Symbol(z, Decl(mappedTypeAsClauses.ts, 3, 53))
|
||||
|
||||
// Mapped type with 'as N' clause has no constraint on 'in T' clause
|
||||
|
||||
type PropDef<K extends keyof any, T> = { name: K, type: T };
|
||||
>PropDef : Symbol(PropDef, Decl(mappedTypeAsClauses.ts, 3, 70))
|
||||
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 7, 13))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 7, 33))
|
||||
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 7, 40))
|
||||
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 7, 13))
|
||||
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 7, 49))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 7, 33))
|
||||
|
||||
type TypeFromDefs<T extends PropDef<keyof any, any>> = { [P in T as P['name']]: P['type'] };
|
||||
>TypeFromDefs : Symbol(TypeFromDefs, Decl(mappedTypeAsClauses.ts, 7, 60))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 9, 18))
|
||||
>PropDef : Symbol(PropDef, Decl(mappedTypeAsClauses.ts, 3, 70))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 9, 18))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
|
||||
|
||||
type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>;
|
||||
>TP1 : Symbol(TP1, Decl(mappedTypeAsClauses.ts, 9, 92))
|
||||
>TypeFromDefs : Symbol(TypeFromDefs, Decl(mappedTypeAsClauses.ts, 7, 60))
|
||||
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 25))
|
||||
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 36))
|
||||
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 55))
|
||||
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 66))
|
||||
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 85))
|
||||
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 96))
|
||||
|
||||
// No array or tuple type mapping when 'as N' clause present
|
||||
|
||||
type TA1 = Getters<string[]>;
|
||||
>TA1 : Symbol(TA1, Decl(mappedTypeAsClauses.ts, 11, 114))
|
||||
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
|
||||
|
||||
type TA2 = Getters<[number, boolean]>;
|
||||
>TA2 : Symbol(TA2, Decl(mappedTypeAsClauses.ts, 15, 29))
|
||||
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
|
||||
|
||||
// Filtering using 'as N' clause
|
||||
|
||||
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
|
||||
>Methods : Symbol(Methods, Decl(mappedTypeAsClauses.ts, 16, 38))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
|
||||
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
|
||||
|
||||
type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>;
|
||||
>TM1 : Symbol(TM1, Decl(mappedTypeAsClauses.ts, 20, 80))
|
||||
>Methods : Symbol(Methods, Decl(mappedTypeAsClauses.ts, 16, 38))
|
||||
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 21, 20))
|
||||
>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 21, 35))
|
||||
>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 21, 40))
|
||||
>baz : Symbol(baz, Decl(mappedTypeAsClauses.ts, 21, 60))
|
||||
|
||||
// Mapping to multiple names using 'as N' clause
|
||||
|
||||
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
|
||||
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
|
||||
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
|
||||
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
|
||||
|
||||
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
|
||||
>TD1 : Symbol(TD1, Decl(mappedTypeAsClauses.ts, 25, 75))
|
||||
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
|
||||
>a : Symbol(a, Decl(mappedTypeAsClauses.ts, 26, 23))
|
||||
>b : Symbol(b, Decl(mappedTypeAsClauses.ts, 26, 34))
|
||||
|
||||
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
|
||||
>TD2 : Symbol(TD2, Decl(mappedTypeAsClauses.ts, 26, 48))
|
||||
>TD1 : Symbol(TD1, Decl(mappedTypeAsClauses.ts, 25, 75))
|
||||
|
||||
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
|
||||
>TD3 : Symbol(TD3, Decl(mappedTypeAsClauses.ts, 27, 21))
|
||||
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9))
|
||||
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
|
||||
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9))
|
||||
|
||||
68
tests/baselines/reference/mappedTypeAsClauses.types
Normal file
68
tests/baselines/reference/mappedTypeAsClauses.types
Normal file
@ -0,0 +1,68 @@
|
||||
=== tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts ===
|
||||
// Mapped type 'as N' clauses
|
||||
|
||||
type Getters<T> = { [P in keyof T & string as `get${capitalize P}`]: () => T[P] };
|
||||
>Getters : Getters<T>
|
||||
|
||||
type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>;
|
||||
>TG1 : Getters<{ foo: string; bar: number; baz: { z: boolean;}; }>
|
||||
>foo : string
|
||||
>bar : number
|
||||
>baz : { z: boolean; }
|
||||
>z : boolean
|
||||
|
||||
// Mapped type with 'as N' clause has no constraint on 'in T' clause
|
||||
|
||||
type PropDef<K extends keyof any, T> = { name: K, type: T };
|
||||
>PropDef : PropDef<K, T>
|
||||
>name : K
|
||||
>type : T
|
||||
|
||||
type TypeFromDefs<T extends PropDef<keyof any, any>> = { [P in T as P['name']]: P['type'] };
|
||||
>TypeFromDefs : TypeFromDefs<T>
|
||||
|
||||
type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>;
|
||||
>TP1 : TypeFromDefs<{ name: 'a'; type: string; } | { name: 'b'; type: number; } | { name: 'a'; type: boolean; }>
|
||||
>name : "a"
|
||||
>type : string
|
||||
>name : "b"
|
||||
>type : number
|
||||
>name : "a"
|
||||
>type : boolean
|
||||
|
||||
// No array or tuple type mapping when 'as N' clause present
|
||||
|
||||
type TA1 = Getters<string[]>;
|
||||
>TA1 : Getters<string[]>
|
||||
|
||||
type TA2 = Getters<[number, boolean]>;
|
||||
>TA2 : Getters<[number, boolean]>
|
||||
|
||||
// Filtering using 'as N' clause
|
||||
|
||||
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
|
||||
>Methods : Methods<T>
|
||||
|
||||
type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>;
|
||||
>TM1 : Methods<{ foo(): number; bar(x: string): boolean; baz: string | number; }>
|
||||
>foo : () => number
|
||||
>bar : (x: string) => boolean
|
||||
>x : string
|
||||
>baz : string | number
|
||||
|
||||
// Mapping to multiple names using 'as N' clause
|
||||
|
||||
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
|
||||
>DoubleProp : DoubleProp<T>
|
||||
|
||||
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
|
||||
>TD1 : DoubleProp<{ a: string; b: number; }>
|
||||
>a : string
|
||||
>b : number
|
||||
|
||||
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
|
||||
>TD2 : "a1" | "b1" | "a2" | "b2"
|
||||
|
||||
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
|
||||
>TD3 : `${keyof U & string}1` | `${keyof U & string}2`
|
||||
|
||||
@ -66,7 +66,7 @@ type B = { b: string };
|
||||
>b : string
|
||||
|
||||
type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
|
||||
>T40 : string | Box<string>[] | Boxified<A> | readonly Box<A>[] | Box<A>[] | [Box<A>, Box<B>]
|
||||
>T40 : string | Box<string>[] | Boxified<A> | readonly Box<A>[] | [Box<A>, Box<B>] | Box<A>[]
|
||||
|
||||
type ReadWrite<T> = { -readonly [P in keyof T] : T[P] };
|
||||
>ReadWrite : ReadWrite<T>
|
||||
|
||||
@ -26,7 +26,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(41,11): error TS2322: Type
|
||||
'{ name: string; prop: boolean; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'any'.
|
||||
tests/cases/compiler/objectLiteralExcessProperties.ts(43,43): error TS2322: Type '{ name: string; prop: true; }' is not assignable to type 'T | { prop: boolean; }'.
|
||||
Object literal may only specify known properties, and 'name' does not exist in type '{ prop: boolean; }'.
|
||||
tests/cases/compiler/objectLiteralExcessProperties.ts(45,76): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '{ name: string; } | (T & { prop: boolean; })'.
|
||||
tests/cases/compiler/objectLiteralExcessProperties.ts(45,76): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '(T & { prop: boolean; }) | { name: string; }'.
|
||||
Object literal may only specify known properties, and 'prop' does not exist in type '{ name: string; }'.
|
||||
tests/cases/compiler/objectLiteralExcessProperties.ts(49,44): error TS2322: Type '{ z: string; }' is not assignable to type 'object & { x: string; }'.
|
||||
Object literal may only specify known properties, and 'z' does not exist in type 'object & { x: string; }'.
|
||||
@ -122,7 +122,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(49,44): error TS2322: Type
|
||||
// Excess property checks only on non-generic parts of unions
|
||||
const obj4: T & { prop: boolean } | { name: string } = { name: "test", prop: true };
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '{ name: string; } | (T & { prop: boolean; })'.
|
||||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '(T & { prop: boolean; }) | { name: string; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'prop' does not exist in type '{ name: string; }'.
|
||||
// No excess property checks when union includes 'object' type
|
||||
const obj5: object | { x: string } = { z: 'abc' }
|
||||
|
||||
@ -132,7 +132,7 @@ function test<T extends IFoo>() {
|
||||
|
||||
// Excess property checks only on non-generic parts of unions
|
||||
const obj4: T & { prop: boolean } | { name: string } = { name: "test", prop: true };
|
||||
>obj4 : { name: string; } | (T & { prop: boolean; })
|
||||
>obj4 : (T & { prop: boolean; }) | { name: string; }
|
||||
>prop : boolean
|
||||
>name : string
|
||||
>{ name: "test", prop: true } : { name: string; prop: boolean; }
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Repro from #38236
|
||||
|
||||
type Type = string | object;
|
||||
>Type : string | object
|
||||
>Type : Type
|
||||
|
||||
class SyncableObject {
|
||||
>SyncableObject : SyncableObject
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts ===
|
||||
type T = "foo" | "bar" | "baz";
|
||||
>T : "foo" | "bar" | "baz"
|
||||
>T : T
|
||||
|
||||
var x: "foo" | "bar" | "baz" = undefined;
|
||||
>x : "foo" | "bar" | "baz"
|
||||
>x : T
|
||||
>undefined : undefined
|
||||
|
||||
var y: T = undefined;
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>y : T
|
||||
>undefined : undefined
|
||||
|
||||
if (x === "foo") {
|
||||
>x === "foo" : boolean
|
||||
>x : "foo" | "bar" | "baz"
|
||||
>x : T
|
||||
>"foo" : "foo"
|
||||
|
||||
let a = x;
|
||||
@ -25,10 +25,10 @@ else if (x !== "bar") {
|
||||
>"bar" : "bar"
|
||||
|
||||
let b = x || y;
|
||||
>b : "foo" | "bar" | "baz"
|
||||
>x || y : "foo" | "bar" | "baz"
|
||||
>b : T
|
||||
>x || y : T
|
||||
>x : "baz"
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>y : T
|
||||
}
|
||||
else {
|
||||
let c = x;
|
||||
@ -36,25 +36,25 @@ else {
|
||||
>x : "bar"
|
||||
|
||||
let d = y;
|
||||
>d : "foo" | "bar" | "baz"
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>d : T
|
||||
>y : T
|
||||
|
||||
let e: (typeof x) | (typeof y) = c || d;
|
||||
>e : "foo" | "bar" | "baz"
|
||||
>e : T
|
||||
>x : "bar"
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>c || d : "foo" | "bar" | "baz"
|
||||
>y : T
|
||||
>c || d : T
|
||||
>c : "bar"
|
||||
>d : "foo" | "bar" | "baz"
|
||||
>d : T
|
||||
}
|
||||
|
||||
x = y;
|
||||
>x = y : "foo" | "bar" | "baz"
|
||||
>x : "foo" | "bar" | "baz"
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>x = y : T
|
||||
>x : T
|
||||
>y : T
|
||||
|
||||
y = x;
|
||||
>y = x : "foo" | "bar" | "baz"
|
||||
>y : "foo" | "bar" | "baz"
|
||||
>x : "foo" | "bar" | "baz"
|
||||
>y = x : T
|
||||
>y : T
|
||||
>x : T
|
||||
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts ===
|
||||
type T = number | "foo" | "bar";
|
||||
>T : number | "foo" | "bar"
|
||||
>T : T
|
||||
|
||||
var x: "foo" | "bar" | number;
|
||||
>x : number | "foo" | "bar"
|
||||
>x : T
|
||||
|
||||
var y: T = undefined;
|
||||
>y : number | "foo" | "bar"
|
||||
>y : T
|
||||
>undefined : undefined
|
||||
|
||||
if (x === "foo") {
|
||||
>x === "foo" : boolean
|
||||
>x : number | "foo" | "bar"
|
||||
>x : T
|
||||
>"foo" : "foo"
|
||||
|
||||
let a = x;
|
||||
@ -24,10 +24,10 @@ else if (x !== "bar") {
|
||||
>"bar" : "bar"
|
||||
|
||||
let b = x || y;
|
||||
>b : number | "foo" | "bar"
|
||||
>x || y : number | "foo" | "bar"
|
||||
>b : T
|
||||
>x || y : T
|
||||
>x : number
|
||||
>y : number | "foo" | "bar"
|
||||
>y : T
|
||||
}
|
||||
else {
|
||||
let c = x;
|
||||
@ -35,25 +35,25 @@ else {
|
||||
>x : "bar"
|
||||
|
||||
let d = y;
|
||||
>d : number | "foo" | "bar"
|
||||
>y : number | "foo" | "bar"
|
||||
>d : T
|
||||
>y : T
|
||||
|
||||
let e: (typeof x) | (typeof y) = c || d;
|
||||
>e : number | "foo" | "bar"
|
||||
>e : T
|
||||
>x : "bar"
|
||||
>y : number | "foo" | "bar"
|
||||
>c || d : number | "foo" | "bar"
|
||||
>y : T
|
||||
>c || d : T
|
||||
>c : "bar"
|
||||
>d : number | "foo" | "bar"
|
||||
>d : T
|
||||
}
|
||||
|
||||
x = y;
|
||||
>x = y : number | "foo" | "bar"
|
||||
>x : number | "foo" | "bar"
|
||||
>y : number | "foo" | "bar"
|
||||
>x = y : T
|
||||
>x : T
|
||||
>y : T
|
||||
|
||||
y = x;
|
||||
>y = x : number | "foo" | "bar"
|
||||
>y : number | "foo" | "bar"
|
||||
>x : number | "foo" | "bar"
|
||||
>y = x : T
|
||||
>y : T
|
||||
>x : T
|
||||
|
||||
|
||||
219
tests/baselines/reference/templateLiteralTypes1.errors.txt
Normal file
219
tests/baselines/reference/templateLiteralTypes1.errors.txt
Normal file
@ -0,0 +1,219 @@
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes1.ts(34,5): error TS2322: Type 'T' is not assignable to type '{ [P in keyof T & string as `p_${P}`]: T[P]; }'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes1.ts(39,5): error TS2322: Type '{ [P in B as `p_${P}`]: T; }' is not assignable to type '{ [Q in A as `p_${Q}`]: U; }'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
'A' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'string' is not assignable to type 'B'.
|
||||
'string' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'string'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes1.ts(184,16): error TS2590: Expression produces a union type that is too complex to represent.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes1.ts(188,16): error TS2590: Expression produces a union type that is too complex to represent.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes1.ts(192,16): error TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/literal/templateLiteralTypes1.ts (5 errors) ====
|
||||
// Template types example from #12754
|
||||
|
||||
const createScopedActionType = <S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}`;
|
||||
const createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
const MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
|
||||
// Union types are distributed over template types
|
||||
|
||||
type EventName<S extends string> = `${S}Changed`;
|
||||
type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
|
||||
// Primitive literal types can be spread into templates
|
||||
|
||||
type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
|
||||
// Casing modifiers
|
||||
|
||||
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
|
||||
type TCA1 = Cases<'bar'>; // 'BAR bar Bar bar'
|
||||
type TCA2 = Cases<'BAR'>; // 'BAR bar BAR bAR'
|
||||
|
||||
// Assignability
|
||||
|
||||
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
|
||||
let s1: string = name;
|
||||
let s2: 'getFoo' | 'getBar' = name;
|
||||
}
|
||||
|
||||
function fa1<T>(x: T, y: { [P in keyof T]: T[P] }, z: { [P in keyof T & string as `p_${P}`]: T[P] }) {
|
||||
y = x;
|
||||
z = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{ [P in keyof T & string as `p_${P}`]: T[P]; }'.
|
||||
}
|
||||
|
||||
function fa2<T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T }, y: { [Q in A as `p_${Q}`]: U }) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type '{ [P in B as `p_${P}`]: T; }' is not assignable to type '{ [Q in A as `p_${Q}`]: U; }'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
!!! error TS2322: 'A' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'B'.
|
||||
!!! error TS2322: 'string' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'string'.
|
||||
}
|
||||
|
||||
// String transformations using recursive conditional types
|
||||
|
||||
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
|
||||
T extends [] ? '' :
|
||||
T extends [unknown] ? `${T[0]}` :
|
||||
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
|
||||
string;
|
||||
|
||||
type TJ1 = Join<[1, 2, 3, 4], '.'>
|
||||
type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
type TJ3 = Join<[], '.'>
|
||||
|
||||
// Inference based on delimiters
|
||||
|
||||
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
|
||||
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
|
||||
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
|
||||
type T22 = MatchPair<' [1,2]'>; // unknown
|
||||
type T23 = MatchPair<'[123]'>; // unknown
|
||||
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
|
||||
|
||||
type SnakeToCamelCase<S extends string> =
|
||||
S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${lowercase T}` :
|
||||
SnakeToPascalCase<S>;
|
||||
|
||||
type SnakeToPascalCase<S extends string> =
|
||||
string extends S ? string :
|
||||
S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${capitalize `${lowercase T}`}` :
|
||||
never;
|
||||
|
||||
type RR0 = SnakeToPascalCase<'hello_world_foo'>; // 'HelloWorldFoo'
|
||||
type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; // 'FooBarBaz'
|
||||
type RR2 = SnakeToCamelCase<'hello_world_foo'>; // 'helloWorldFoo'
|
||||
type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; // 'fooBarBaz'
|
||||
|
||||
// Single character inference
|
||||
|
||||
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
|
||||
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
|
||||
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
|
||||
type T27 = FirstTwoAndRest<'a'>; // unknown
|
||||
|
||||
type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
|
||||
type TC1 = Capitalize<'foo'>; // 'Foo'
|
||||
type TC2 = Uncapitalize<'Foo'>; // 'foo'
|
||||
|
||||
type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |'8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
|
||||
type HexColor<S extends string> =
|
||||
S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ?
|
||||
[R1, R2, G1, G2, B1, B2] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ?
|
||||
S :
|
||||
never :
|
||||
never;
|
||||
|
||||
type TH1 = HexColor<'#8080FF'>; // '#8080FF'
|
||||
type TH2 = HexColor<'#80c0ff'>; // '#80c0ff'
|
||||
type TH3 = HexColor<'#8080F'>; // never
|
||||
type TH4 = HexColor<'#8080FFF'>; // never
|
||||
|
||||
// Recursive inference
|
||||
|
||||
type Trim<S extends string> =
|
||||
S extends ` ${infer T}` ? Trim<T> :
|
||||
S extends `${infer T} ` ? Trim<T> :
|
||||
S;
|
||||
|
||||
type TR1 = Trim<'xx '>; // 'xx'
|
||||
type TR2 = Trim<' xx'>; // 'xx'
|
||||
type TR3 = Trim<' xx '>; // 'xx'
|
||||
|
||||
type Split<S extends string, D extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends '' ? [] :
|
||||
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
|
||||
[S];
|
||||
|
||||
type T40 = Split<'foo', '.'>; // ['foo']
|
||||
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
|
||||
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
|
||||
type T43 = Split<any, '.'>; // string[]
|
||||
|
||||
// Inference and property name paths
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
|
||||
let p1 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a');
|
||||
let p2 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b');
|
||||
let p3 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d');
|
||||
|
||||
type PropType<T, Path extends string> =
|
||||
string extends Path ? unknown :
|
||||
Path extends keyof T ? T[Path] :
|
||||
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
|
||||
unknown;
|
||||
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
declare const s: string;
|
||||
|
||||
const obj = { a: { b: {c: 42, d: 'hello' }}};
|
||||
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
getPropValue(obj, s); // unknown
|
||||
|
||||
// Infer type variables in template literals have string constraint
|
||||
|
||||
type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
type S2<S extends string> = S;
|
||||
|
||||
// Batched single character inferences for lower recursion depth
|
||||
|
||||
type Chars<S extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] :
|
||||
S extends `${infer C}${infer R}` ? [C, ...Chars<R>] :
|
||||
S extends '' ? [] :
|
||||
never;
|
||||
|
||||
type L1 = Chars<'FooBarBazThisIsALongerString'>; // ['F', 'o', 'o', 'B', 'a', 'r', ...]
|
||||
|
||||
// Cross product unions limited to 100,000 constituents
|
||||
|
||||
type A = any;
|
||||
|
||||
type U1 = {a1:A} | {b1:A} | {c1:A} | {d1:A} | {e1:A} | {f1:A} | {g1:A} | {h1:A} | {i1:A} | {j1:A};
|
||||
type U2 = {a2:A} | {b2:A} | {c2:A} | {d2:A} | {e2:A} | {f2:A} | {g2:A} | {h2:A} | {i2:A} | {j2:A};
|
||||
type U3 = {a3:A} | {b3:A} | {c3:A} | {d3:A} | {e3:A} | {f3:A} | {g3:A} | {h3:A} | {i3:A} | {j3:A};
|
||||
type U4 = {a4:A} | {b4:A} | {c4:A} | {d4:A} | {e4:A} | {f4:A} | {g4:A} | {h4:A} | {i4:A} | {j4:A};
|
||||
type U5 = {a5:A} | {b5:A} | {c5:A} | {d5:A} | {e5:A} | {f5:A} | {g5:A} | {h5:A} | {i5:A} | {j5:A};
|
||||
|
||||
type U100000 = U1 & U2 & U3 & U4 & U5; // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
||||
type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
|
||||
type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
||||
type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
|
||||
type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
||||
437
tests/baselines/reference/templateLiteralTypes1.js
Normal file
437
tests/baselines/reference/templateLiteralTypes1.js
Normal file
@ -0,0 +1,437 @@
|
||||
//// [templateLiteralTypes1.ts]
|
||||
// Template types example from #12754
|
||||
|
||||
const createScopedActionType = <S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}`;
|
||||
const createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
const MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
|
||||
// Union types are distributed over template types
|
||||
|
||||
type EventName<S extends string> = `${S}Changed`;
|
||||
type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
|
||||
// Primitive literal types can be spread into templates
|
||||
|
||||
type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
|
||||
// Casing modifiers
|
||||
|
||||
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
|
||||
type TCA1 = Cases<'bar'>; // 'BAR bar Bar bar'
|
||||
type TCA2 = Cases<'BAR'>; // 'BAR bar BAR bAR'
|
||||
|
||||
// Assignability
|
||||
|
||||
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
|
||||
let s1: string = name;
|
||||
let s2: 'getFoo' | 'getBar' = name;
|
||||
}
|
||||
|
||||
function fa1<T>(x: T, y: { [P in keyof T]: T[P] }, z: { [P in keyof T & string as `p_${P}`]: T[P] }) {
|
||||
y = x;
|
||||
z = x; // Error
|
||||
}
|
||||
|
||||
function fa2<T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T }, y: { [Q in A as `p_${Q}`]: U }) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
// String transformations using recursive conditional types
|
||||
|
||||
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
|
||||
T extends [] ? '' :
|
||||
T extends [unknown] ? `${T[0]}` :
|
||||
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
|
||||
string;
|
||||
|
||||
type TJ1 = Join<[1, 2, 3, 4], '.'>
|
||||
type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
type TJ3 = Join<[], '.'>
|
||||
|
||||
// Inference based on delimiters
|
||||
|
||||
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
|
||||
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
|
||||
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
|
||||
type T22 = MatchPair<' [1,2]'>; // unknown
|
||||
type T23 = MatchPair<'[123]'>; // unknown
|
||||
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
|
||||
|
||||
type SnakeToCamelCase<S extends string> =
|
||||
S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${lowercase T}` :
|
||||
SnakeToPascalCase<S>;
|
||||
|
||||
type SnakeToPascalCase<S extends string> =
|
||||
string extends S ? string :
|
||||
S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${capitalize `${lowercase T}`}` :
|
||||
never;
|
||||
|
||||
type RR0 = SnakeToPascalCase<'hello_world_foo'>; // 'HelloWorldFoo'
|
||||
type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; // 'FooBarBaz'
|
||||
type RR2 = SnakeToCamelCase<'hello_world_foo'>; // 'helloWorldFoo'
|
||||
type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; // 'fooBarBaz'
|
||||
|
||||
// Single character inference
|
||||
|
||||
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
|
||||
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
|
||||
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
|
||||
type T27 = FirstTwoAndRest<'a'>; // unknown
|
||||
|
||||
type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
|
||||
type TC1 = Capitalize<'foo'>; // 'Foo'
|
||||
type TC2 = Uncapitalize<'Foo'>; // 'foo'
|
||||
|
||||
type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |'8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
|
||||
type HexColor<S extends string> =
|
||||
S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ?
|
||||
[R1, R2, G1, G2, B1, B2] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ?
|
||||
S :
|
||||
never :
|
||||
never;
|
||||
|
||||
type TH1 = HexColor<'#8080FF'>; // '#8080FF'
|
||||
type TH2 = HexColor<'#80c0ff'>; // '#80c0ff'
|
||||
type TH3 = HexColor<'#8080F'>; // never
|
||||
type TH4 = HexColor<'#8080FFF'>; // never
|
||||
|
||||
// Recursive inference
|
||||
|
||||
type Trim<S extends string> =
|
||||
S extends ` ${infer T}` ? Trim<T> :
|
||||
S extends `${infer T} ` ? Trim<T> :
|
||||
S;
|
||||
|
||||
type TR1 = Trim<'xx '>; // 'xx'
|
||||
type TR2 = Trim<' xx'>; // 'xx'
|
||||
type TR3 = Trim<' xx '>; // 'xx'
|
||||
|
||||
type Split<S extends string, D extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends '' ? [] :
|
||||
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
|
||||
[S];
|
||||
|
||||
type T40 = Split<'foo', '.'>; // ['foo']
|
||||
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
|
||||
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
|
||||
type T43 = Split<any, '.'>; // string[]
|
||||
|
||||
// Inference and property name paths
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
|
||||
let p1 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a');
|
||||
let p2 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b');
|
||||
let p3 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d');
|
||||
|
||||
type PropType<T, Path extends string> =
|
||||
string extends Path ? unknown :
|
||||
Path extends keyof T ? T[Path] :
|
||||
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
|
||||
unknown;
|
||||
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
declare const s: string;
|
||||
|
||||
const obj = { a: { b: {c: 42, d: 'hello' }}};
|
||||
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
getPropValue(obj, s); // unknown
|
||||
|
||||
// Infer type variables in template literals have string constraint
|
||||
|
||||
type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
type S2<S extends string> = S;
|
||||
|
||||
// Batched single character inferences for lower recursion depth
|
||||
|
||||
type Chars<S extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] :
|
||||
S extends `${infer C}${infer R}` ? [C, ...Chars<R>] :
|
||||
S extends '' ? [] :
|
||||
never;
|
||||
|
||||
type L1 = Chars<'FooBarBazThisIsALongerString'>; // ['F', 'o', 'o', 'B', 'a', 'r', ...]
|
||||
|
||||
// Cross product unions limited to 100,000 constituents
|
||||
|
||||
type A = any;
|
||||
|
||||
type U1 = {a1:A} | {b1:A} | {c1:A} | {d1:A} | {e1:A} | {f1:A} | {g1:A} | {h1:A} | {i1:A} | {j1:A};
|
||||
type U2 = {a2:A} | {b2:A} | {c2:A} | {d2:A} | {e2:A} | {f2:A} | {g2:A} | {h2:A} | {i2:A} | {j2:A};
|
||||
type U3 = {a3:A} | {b3:A} | {c3:A} | {d3:A} | {e3:A} | {f3:A} | {g3:A} | {h3:A} | {i3:A} | {j3:A};
|
||||
type U4 = {a4:A} | {b4:A} | {c4:A} | {d4:A} | {e4:A} | {f4:A} | {g4:A} | {h4:A} | {i4:A} | {j4:A};
|
||||
type U5 = {a5:A} | {b5:A} | {c5:A} | {d5:A} | {e5:A} | {f5:A} | {g5:A} | {h5:A} | {i5:A} | {j5:A};
|
||||
|
||||
type U100000 = U1 & U2 & U3 & U4 & U5; // Error
|
||||
|
||||
type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
|
||||
type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; // Error
|
||||
|
||||
type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
|
||||
type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; // Error
|
||||
|
||||
|
||||
//// [templateLiteralTypes1.js]
|
||||
"use strict";
|
||||
// Template types example from #12754
|
||||
var createScopedActionType = function (scope) { return function (type) { return scope + "/" + type; }; };
|
||||
var createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
var MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
// Assignability
|
||||
function test(name) {
|
||||
var s1 = name;
|
||||
var s2 = name;
|
||||
}
|
||||
function fa1(x, y, z) {
|
||||
y = x;
|
||||
z = x; // Error
|
||||
}
|
||||
function fa2(x, y) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
var p1 = getProp({ a: { b: { c: 42, d: 'hello' } } }, 'a');
|
||||
var p2 = getProp({ a: { b: { c: 42, d: 'hello' } } }, 'a.b');
|
||||
var p3 = getProp({ a: { b: { c: 42, d: 'hello' } } }, 'a.b.d');
|
||||
var obj = { a: { b: { c: 42, d: 'hello' } } };
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
getPropValue(obj, s); // unknown
|
||||
|
||||
|
||||
//// [templateLiteralTypes1.d.ts]
|
||||
declare const createScopedActionType: <S extends string>(scope: S) => <T extends string>(type: T) => `${S}/${T}`;
|
||||
declare const createActionInMyScope: <T extends string>(type: T) => `MyScope/${T}`;
|
||||
declare const MY_ACTION: "MyScope/MY_ACTION";
|
||||
declare type EventName<S extends string> = `${S}Changed`;
|
||||
declare type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
declare type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
declare type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
declare type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
declare type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
declare type TCA1 = Cases<'bar'>;
|
||||
declare type TCA2 = Cases<'BAR'>;
|
||||
declare function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`): void;
|
||||
declare function fa1<T>(x: T, y: {
|
||||
[P in keyof T]: T[P];
|
||||
}, z: {
|
||||
[P in keyof T & string as `p_${P}`]: T[P];
|
||||
}): void;
|
||||
declare function fa2<T, U extends T, A extends string, B extends A>(x: {
|
||||
[P in B as `p_${P}`]: T;
|
||||
}, y: {
|
||||
[Q in A as `p_${Q}`]: U;
|
||||
}): void;
|
||||
declare type Join<T extends (string | number | boolean | bigint)[], D extends string> = T extends [] ? '' : T extends [unknown] ? `${T[0]}` : T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` : string;
|
||||
declare type TJ1 = Join<[1, 2, 3, 4], '.'>;
|
||||
declare type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
declare type TJ3 = Join<[], '.'>;
|
||||
declare type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
declare type T20 = MatchPair<'[1,2]'>;
|
||||
declare type T21 = MatchPair<'[foo,bar]'>;
|
||||
declare type T22 = MatchPair<' [1,2]'>;
|
||||
declare type T23 = MatchPair<'[123]'>;
|
||||
declare type T24 = MatchPair<'[1,2,3,4]'>;
|
||||
declare type SnakeToCamelCase<S extends string> = S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` : S extends `${infer T}` ? `${lowercase T}` : SnakeToPascalCase<S>;
|
||||
declare type SnakeToPascalCase<S extends string> = string extends S ? string : S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` : S extends `${infer T}` ? `${capitalize `${lowercase T}`}` : never;
|
||||
declare type RR0 = SnakeToPascalCase<'hello_world_foo'>;
|
||||
declare type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>;
|
||||
declare type RR2 = SnakeToCamelCase<'hello_world_foo'>;
|
||||
declare type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>;
|
||||
declare type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
declare type T25 = FirstTwoAndRest<'abcde'>;
|
||||
declare type T26 = FirstTwoAndRest<'ab'>;
|
||||
declare type T27 = FirstTwoAndRest<'a'>;
|
||||
declare type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
declare type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
declare type TC1 = Capitalize<'foo'>;
|
||||
declare type TC2 = Uncapitalize<'Foo'>;
|
||||
declare type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
declare type HexColor<S extends string> = S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ? [
|
||||
R1,
|
||||
R2,
|
||||
G1,
|
||||
G2,
|
||||
B1,
|
||||
B2
|
||||
] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ? S : never : never;
|
||||
declare type TH1 = HexColor<'#8080FF'>;
|
||||
declare type TH2 = HexColor<'#80c0ff'>;
|
||||
declare type TH3 = HexColor<'#8080F'>;
|
||||
declare type TH4 = HexColor<'#8080FFF'>;
|
||||
declare type Trim<S extends string> = S extends ` ${infer T}` ? Trim<T> : S extends `${infer T} ` ? Trim<T> : S;
|
||||
declare type TR1 = Trim<'xx '>;
|
||||
declare type TR2 = Trim<' xx'>;
|
||||
declare type TR3 = Trim<' xx '>;
|
||||
declare type Split<S extends string, D extends string> = string extends S ? string[] : S extends '' ? [] : S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [
|
||||
S
|
||||
];
|
||||
declare type T40 = Split<'foo', '.'>;
|
||||
declare type T41 = Split<'foo.bar.baz', '.'>;
|
||||
declare type T42 = Split<'foo.bar', ''>;
|
||||
declare type T43 = Split<any, '.'>;
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
declare let p1: {
|
||||
readonly b: {
|
||||
readonly c: 42;
|
||||
readonly d: "hello";
|
||||
};
|
||||
};
|
||||
declare let p2: {
|
||||
readonly c: 42;
|
||||
readonly d: "hello";
|
||||
};
|
||||
declare let p3: "hello";
|
||||
declare type PropType<T, Path extends string> = string extends Path ? unknown : Path extends keyof T ? T[Path] : Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown : unknown;
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
declare const s: string;
|
||||
declare const obj: {
|
||||
a: {
|
||||
b: {
|
||||
c: number;
|
||||
d: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
declare type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
declare type S2<S extends string> = S;
|
||||
declare type Chars<S extends string> = string extends S ? string[] : S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] : S extends `${infer C}${infer R}` ? [C, ...Chars<R>] : S extends '' ? [] : never;
|
||||
declare type L1 = Chars<'FooBarBazThisIsALongerString'>;
|
||||
declare type A = any;
|
||||
declare type U1 = {
|
||||
a1: A;
|
||||
} | {
|
||||
b1: A;
|
||||
} | {
|
||||
c1: A;
|
||||
} | {
|
||||
d1: A;
|
||||
} | {
|
||||
e1: A;
|
||||
} | {
|
||||
f1: A;
|
||||
} | {
|
||||
g1: A;
|
||||
} | {
|
||||
h1: A;
|
||||
} | {
|
||||
i1: A;
|
||||
} | {
|
||||
j1: A;
|
||||
};
|
||||
declare type U2 = {
|
||||
a2: A;
|
||||
} | {
|
||||
b2: A;
|
||||
} | {
|
||||
c2: A;
|
||||
} | {
|
||||
d2: A;
|
||||
} | {
|
||||
e2: A;
|
||||
} | {
|
||||
f2: A;
|
||||
} | {
|
||||
g2: A;
|
||||
} | {
|
||||
h2: A;
|
||||
} | {
|
||||
i2: A;
|
||||
} | {
|
||||
j2: A;
|
||||
};
|
||||
declare type U3 = {
|
||||
a3: A;
|
||||
} | {
|
||||
b3: A;
|
||||
} | {
|
||||
c3: A;
|
||||
} | {
|
||||
d3: A;
|
||||
} | {
|
||||
e3: A;
|
||||
} | {
|
||||
f3: A;
|
||||
} | {
|
||||
g3: A;
|
||||
} | {
|
||||
h3: A;
|
||||
} | {
|
||||
i3: A;
|
||||
} | {
|
||||
j3: A;
|
||||
};
|
||||
declare type U4 = {
|
||||
a4: A;
|
||||
} | {
|
||||
b4: A;
|
||||
} | {
|
||||
c4: A;
|
||||
} | {
|
||||
d4: A;
|
||||
} | {
|
||||
e4: A;
|
||||
} | {
|
||||
f4: A;
|
||||
} | {
|
||||
g4: A;
|
||||
} | {
|
||||
h4: A;
|
||||
} | {
|
||||
i4: A;
|
||||
} | {
|
||||
j4: A;
|
||||
};
|
||||
declare type U5 = {
|
||||
a5: A;
|
||||
} | {
|
||||
b5: A;
|
||||
} | {
|
||||
c5: A;
|
||||
} | {
|
||||
d5: A;
|
||||
} | {
|
||||
e5: A;
|
||||
} | {
|
||||
f5: A;
|
||||
} | {
|
||||
g5: A;
|
||||
} | {
|
||||
h5: A;
|
||||
} | {
|
||||
i5: A;
|
||||
} | {
|
||||
j5: A;
|
||||
};
|
||||
declare type U100000 = U1 & U2 & U3 & U4 & U5;
|
||||
declare type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
declare type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`;
|
||||
declare type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
declare type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits];
|
||||
813
tests/baselines/reference/templateLiteralTypes1.symbols
Normal file
813
tests/baselines/reference/templateLiteralTypes1.symbols
Normal file
@ -0,0 +1,813 @@
|
||||
=== tests/cases/conformance/types/literal/templateLiteralTypes1.ts ===
|
||||
// Template types example from #12754
|
||||
|
||||
const createScopedActionType = <S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}`;
|
||||
>createScopedActionType : Symbol(createScopedActionType, Decl(templateLiteralTypes1.ts, 2, 5))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 2, 32))
|
||||
>scope : Symbol(scope, Decl(templateLiteralTypes1.ts, 2, 50))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 2, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 2, 64))
|
||||
>type : Symbol(type, Decl(templateLiteralTypes1.ts, 2, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 2, 64))
|
||||
>scope : Symbol(scope, Decl(templateLiteralTypes1.ts, 2, 50))
|
||||
>type : Symbol(type, Decl(templateLiteralTypes1.ts, 2, 82))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 2, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 2, 64))
|
||||
|
||||
const createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
>createActionInMyScope : Symbol(createActionInMyScope, Decl(templateLiteralTypes1.ts, 3, 5))
|
||||
>createScopedActionType : Symbol(createScopedActionType, Decl(templateLiteralTypes1.ts, 2, 5))
|
||||
|
||||
const MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
>MY_ACTION : Symbol(MY_ACTION, Decl(templateLiteralTypes1.ts, 4, 5))
|
||||
>createActionInMyScope : Symbol(createActionInMyScope, Decl(templateLiteralTypes1.ts, 3, 5))
|
||||
|
||||
// Union types are distributed over template types
|
||||
|
||||
type EventName<S extends string> = `${S}Changed`;
|
||||
>EventName : Symbol(EventName, Decl(templateLiteralTypes1.ts, 4, 53))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 8, 15))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 8, 15))
|
||||
|
||||
type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
>EN1 : Symbol(EN1, Decl(templateLiteralTypes1.ts, 8, 49))
|
||||
>EventName : Symbol(EventName, Decl(templateLiteralTypes1.ts, 4, 53))
|
||||
|
||||
type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
>Loc : Symbol(Loc, Decl(templateLiteralTypes1.ts, 9, 44))
|
||||
|
||||
// Primitive literal types can be spread into templates
|
||||
|
||||
type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
>ToString : Symbol(ToString, Decl(templateLiteralTypes1.ts, 10, 75))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 14, 14))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 14, 14))
|
||||
|
||||
type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
>TS1 : Symbol(TS1, Decl(templateLiteralTypes1.ts, 14, 69))
|
||||
>ToString : Symbol(ToString, Decl(templateLiteralTypes1.ts, 10, 75))
|
||||
|
||||
// Casing modifiers
|
||||
|
||||
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
>Cases : Symbol(Cases, Decl(templateLiteralTypes1.ts, 15, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 19, 11))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 19, 11))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 19, 11))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 19, 11))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 19, 11))
|
||||
|
||||
type TCA1 = Cases<'bar'>; // 'BAR bar Bar bar'
|
||||
>TCA1 : Symbol(TCA1, Decl(templateLiteralTypes1.ts, 19, 97))
|
||||
>Cases : Symbol(Cases, Decl(templateLiteralTypes1.ts, 15, 48))
|
||||
|
||||
type TCA2 = Cases<'BAR'>; // 'BAR bar BAR bAR'
|
||||
>TCA2 : Symbol(TCA2, Decl(templateLiteralTypes1.ts, 21, 25))
|
||||
>Cases : Symbol(Cases, Decl(templateLiteralTypes1.ts, 15, 48))
|
||||
|
||||
// Assignability
|
||||
|
||||
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
|
||||
>test : Symbol(test, Decl(templateLiteralTypes1.ts, 22, 25))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 26, 14))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes1.ts, 26, 39))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 26, 14))
|
||||
|
||||
let s1: string = name;
|
||||
>s1 : Symbol(s1, Decl(templateLiteralTypes1.ts, 27, 7))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes1.ts, 26, 39))
|
||||
|
||||
let s2: 'getFoo' | 'getBar' = name;
|
||||
>s2 : Symbol(s2, Decl(templateLiteralTypes1.ts, 28, 7))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes1.ts, 26, 39))
|
||||
}
|
||||
|
||||
function fa1<T>(x: T, y: { [P in keyof T]: T[P] }, z: { [P in keyof T & string as `p_${P}`]: T[P] }) {
|
||||
>fa1 : Symbol(fa1, Decl(templateLiteralTypes1.ts, 29, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 31, 16))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>y : Symbol(y, Decl(templateLiteralTypes1.ts, 31, 21))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 31, 28))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 31, 28))
|
||||
>z : Symbol(z, Decl(templateLiteralTypes1.ts, 31, 50))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 31, 57))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 31, 57))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 31, 13))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 31, 57))
|
||||
|
||||
y = x;
|
||||
>y : Symbol(y, Decl(templateLiteralTypes1.ts, 31, 21))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 31, 16))
|
||||
|
||||
z = x; // Error
|
||||
>z : Symbol(z, Decl(templateLiteralTypes1.ts, 31, 50))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 31, 16))
|
||||
}
|
||||
|
||||
function fa2<T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T }, y: { [Q in A as `p_${Q}`]: U }) {
|
||||
>fa2 : Symbol(fa2, Decl(templateLiteralTypes1.ts, 34, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 36, 13))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 36, 15))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 36, 13))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 36, 28))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 36, 46))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 36, 28))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 36, 60))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 36, 66))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 36, 46))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 36, 66))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 36, 13))
|
||||
>y : Symbol(y, Decl(templateLiteralTypes1.ts, 36, 91))
|
||||
>Q : Symbol(Q, Decl(templateLiteralTypes1.ts, 36, 98))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 36, 28))
|
||||
>Q : Symbol(Q, Decl(templateLiteralTypes1.ts, 36, 98))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 36, 15))
|
||||
|
||||
x = y;
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 36, 60))
|
||||
>y : Symbol(y, Decl(templateLiteralTypes1.ts, 36, 91))
|
||||
|
||||
y = x; // Error
|
||||
>y : Symbol(y, Decl(templateLiteralTypes1.ts, 36, 91))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes1.ts, 36, 60))
|
||||
}
|
||||
|
||||
// String transformations using recursive conditional types
|
||||
|
||||
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
|
||||
>Join : Symbol(Join, Decl(templateLiteralTypes1.ts, 39, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 43, 59))
|
||||
|
||||
T extends [] ? '' :
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
|
||||
T extends [unknown] ? `${T[0]}` :
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
|
||||
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 46, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 43, 10))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 43, 59))
|
||||
>Join : Symbol(Join, Decl(templateLiteralTypes1.ts, 39, 1))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 46, 32))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 43, 59))
|
||||
|
||||
string;
|
||||
|
||||
type TJ1 = Join<[1, 2, 3, 4], '.'>
|
||||
>TJ1 : Symbol(TJ1, Decl(templateLiteralTypes1.ts, 47, 11))
|
||||
>Join : Symbol(Join, Decl(templateLiteralTypes1.ts, 39, 1))
|
||||
|
||||
type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
>TJ2 : Symbol(TJ2, Decl(templateLiteralTypes1.ts, 49, 34))
|
||||
>Join : Symbol(Join, Decl(templateLiteralTypes1.ts, 39, 1))
|
||||
|
||||
type TJ3 = Join<[], '.'>
|
||||
>TJ3 : Symbol(TJ3, Decl(templateLiteralTypes1.ts, 50, 44))
|
||||
>Join : Symbol(Join, Decl(templateLiteralTypes1.ts, 39, 1))
|
||||
|
||||
// Inference based on delimiters
|
||||
|
||||
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 55, 15))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 55, 15))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 55, 54))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 55, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 55, 54))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 55, 65))
|
||||
|
||||
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
|
||||
>T20 : Symbol(T20, Decl(templateLiteralTypes1.ts, 55, 90))
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
|
||||
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
|
||||
>T21 : Symbol(T21, Decl(templateLiteralTypes1.ts, 57, 30))
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
|
||||
type T22 = MatchPair<' [1,2]'>; // unknown
|
||||
>T22 : Symbol(T22, Decl(templateLiteralTypes1.ts, 58, 34))
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
|
||||
type T23 = MatchPair<'[123]'>; // unknown
|
||||
>T23 : Symbol(T23, Decl(templateLiteralTypes1.ts, 59, 31))
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
|
||||
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
|
||||
>T24 : Symbol(T24, Decl(templateLiteralTypes1.ts, 60, 30))
|
||||
>MatchPair : Symbol(MatchPair, Decl(templateLiteralTypes1.ts, 51, 24))
|
||||
|
||||
type SnakeToCamelCase<S extends string> =
|
||||
>SnakeToCamelCase : Symbol(SnakeToCamelCase, Decl(templateLiteralTypes1.ts, 61, 34))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 63, 22))
|
||||
|
||||
S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 63, 22))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 64, 22))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 64, 33))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 64, 22))
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 64, 33))
|
||||
|
||||
S extends `${infer T}` ? `${lowercase T}` :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 63, 22))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 65, 22))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 65, 22))
|
||||
|
||||
SnakeToPascalCase<S>;
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 63, 22))
|
||||
|
||||
type SnakeToPascalCase<S extends string> =
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 68, 23))
|
||||
|
||||
string extends S ? string :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 68, 23))
|
||||
|
||||
S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 68, 23))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 70, 22))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 70, 33))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 70, 22))
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 70, 33))
|
||||
|
||||
S extends `${infer T}` ? `${capitalize `${lowercase T}`}` :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 68, 23))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 71, 22))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 71, 22))
|
||||
|
||||
never;
|
||||
|
||||
type RR0 = SnakeToPascalCase<'hello_world_foo'>; // 'HelloWorldFoo'
|
||||
>RR0 : Symbol(RR0, Decl(templateLiteralTypes1.ts, 72, 10))
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
|
||||
type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; // 'FooBarBaz'
|
||||
>RR1 : Symbol(RR1, Decl(templateLiteralTypes1.ts, 74, 48))
|
||||
>SnakeToPascalCase : Symbol(SnakeToPascalCase, Decl(templateLiteralTypes1.ts, 66, 25))
|
||||
|
||||
type RR2 = SnakeToCamelCase<'hello_world_foo'>; // 'helloWorldFoo'
|
||||
>RR2 : Symbol(RR2, Decl(templateLiteralTypes1.ts, 75, 44))
|
||||
>SnakeToCamelCase : Symbol(SnakeToCamelCase, Decl(templateLiteralTypes1.ts, 61, 34))
|
||||
|
||||
type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; // 'fooBarBaz'
|
||||
>RR3 : Symbol(RR3, Decl(templateLiteralTypes1.ts, 76, 47))
|
||||
>SnakeToCamelCase : Symbol(SnakeToCamelCase, Decl(templateLiteralTypes1.ts, 61, 34))
|
||||
|
||||
// Single character inference
|
||||
|
||||
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
>FirstTwoAndRest : Symbol(FirstTwoAndRest, Decl(templateLiteralTypes1.ts, 77, 43))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 81, 21))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 81, 21))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 81, 59))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 81, 69))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 81, 79))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 81, 59))
|
||||
>B : Symbol(B, Decl(templateLiteralTypes1.ts, 81, 69))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 81, 79))
|
||||
|
||||
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
|
||||
>T25 : Symbol(T25, Decl(templateLiteralTypes1.ts, 81, 112))
|
||||
>FirstTwoAndRest : Symbol(FirstTwoAndRest, Decl(templateLiteralTypes1.ts, 77, 43))
|
||||
|
||||
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
|
||||
>T26 : Symbol(T26, Decl(templateLiteralTypes1.ts, 83, 36))
|
||||
>FirstTwoAndRest : Symbol(FirstTwoAndRest, Decl(templateLiteralTypes1.ts, 77, 43))
|
||||
|
||||
type T27 = FirstTwoAndRest<'a'>; // unknown
|
||||
>T27 : Symbol(T27, Decl(templateLiteralTypes1.ts, 84, 33))
|
||||
>FirstTwoAndRest : Symbol(FirstTwoAndRest, Decl(templateLiteralTypes1.ts, 77, 43))
|
||||
|
||||
type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
>Capitalize : Symbol(Capitalize, Decl(templateLiteralTypes1.ts, 85, 32))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 87, 16))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 87, 16))
|
||||
>H : Symbol(H, Decl(templateLiteralTypes1.ts, 87, 54))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 87, 64))
|
||||
>H : Symbol(H, Decl(templateLiteralTypes1.ts, 87, 54))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 87, 64))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 87, 16))
|
||||
|
||||
type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
>Uncapitalize : Symbol(Uncapitalize, Decl(templateLiteralTypes1.ts, 87, 96))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 88, 18))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 88, 18))
|
||||
>H : Symbol(H, Decl(templateLiteralTypes1.ts, 88, 56))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 88, 66))
|
||||
>H : Symbol(H, Decl(templateLiteralTypes1.ts, 88, 56))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 88, 66))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 88, 18))
|
||||
|
||||
type TC1 = Capitalize<'foo'>; // 'Foo'
|
||||
>TC1 : Symbol(TC1, Decl(templateLiteralTypes1.ts, 88, 98))
|
||||
>Capitalize : Symbol(Capitalize, Decl(templateLiteralTypes1.ts, 85, 32))
|
||||
|
||||
type TC2 = Uncapitalize<'Foo'>; // 'foo'
|
||||
>TC2 : Symbol(TC2, Decl(templateLiteralTypes1.ts, 90, 29))
|
||||
>Uncapitalize : Symbol(Uncapitalize, Decl(templateLiteralTypes1.ts, 87, 96))
|
||||
|
||||
type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |'8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
|
||||
type HexColor<S extends string> =
|
||||
>HexColor : Symbol(HexColor, Decl(templateLiteralTypes1.ts, 93, 145))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 95, 14))
|
||||
|
||||
S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ?
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 95, 14))
|
||||
>R1 : Symbol(R1, Decl(templateLiteralTypes1.ts, 96, 23))
|
||||
>R2 : Symbol(R2, Decl(templateLiteralTypes1.ts, 96, 34))
|
||||
>G1 : Symbol(G1, Decl(templateLiteralTypes1.ts, 96, 45))
|
||||
>G2 : Symbol(G2, Decl(templateLiteralTypes1.ts, 96, 56))
|
||||
>B1 : Symbol(B1, Decl(templateLiteralTypes1.ts, 96, 67))
|
||||
>B2 : Symbol(B2, Decl(templateLiteralTypes1.ts, 96, 78))
|
||||
|
||||
[R1, R2, G1, G2, B1, B2] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ?
|
||||
>R1 : Symbol(R1, Decl(templateLiteralTypes1.ts, 96, 23))
|
||||
>R2 : Symbol(R2, Decl(templateLiteralTypes1.ts, 96, 34))
|
||||
>G1 : Symbol(G1, Decl(templateLiteralTypes1.ts, 96, 45))
|
||||
>G2 : Symbol(G2, Decl(templateLiteralTypes1.ts, 96, 56))
|
||||
>B1 : Symbol(B1, Decl(templateLiteralTypes1.ts, 96, 67))
|
||||
>B2 : Symbol(B2, Decl(templateLiteralTypes1.ts, 96, 78))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
>HexDigit : Symbol(HexDigit, Decl(templateLiteralTypes1.ts, 91, 31))
|
||||
|
||||
S :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 95, 14))
|
||||
|
||||
never :
|
||||
never;
|
||||
|
||||
type TH1 = HexColor<'#8080FF'>; // '#8080FF'
|
||||
>TH1 : Symbol(TH1, Decl(templateLiteralTypes1.ts, 100, 14))
|
||||
>HexColor : Symbol(HexColor, Decl(templateLiteralTypes1.ts, 93, 145))
|
||||
|
||||
type TH2 = HexColor<'#80c0ff'>; // '#80c0ff'
|
||||
>TH2 : Symbol(TH2, Decl(templateLiteralTypes1.ts, 102, 31))
|
||||
>HexColor : Symbol(HexColor, Decl(templateLiteralTypes1.ts, 93, 145))
|
||||
|
||||
type TH3 = HexColor<'#8080F'>; // never
|
||||
>TH3 : Symbol(TH3, Decl(templateLiteralTypes1.ts, 103, 31))
|
||||
>HexColor : Symbol(HexColor, Decl(templateLiteralTypes1.ts, 93, 145))
|
||||
|
||||
type TH4 = HexColor<'#8080FFF'>; // never
|
||||
>TH4 : Symbol(TH4, Decl(templateLiteralTypes1.ts, 104, 30))
|
||||
>HexColor : Symbol(HexColor, Decl(templateLiteralTypes1.ts, 93, 145))
|
||||
|
||||
// Recursive inference
|
||||
|
||||
type Trim<S extends string> =
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 109, 10))
|
||||
|
||||
S extends ` ${infer T}` ? Trim<T> :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 109, 10))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 110, 23))
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 110, 23))
|
||||
|
||||
S extends `${infer T} ` ? Trim<T> :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 109, 10))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 111, 22))
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 111, 22))
|
||||
|
||||
S;
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 109, 10))
|
||||
|
||||
type TR1 = Trim<'xx '>; // 'xx'
|
||||
>TR1 : Symbol(TR1, Decl(templateLiteralTypes1.ts, 112, 6))
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
|
||||
type TR2 = Trim<' xx'>; // 'xx'
|
||||
>TR2 : Symbol(TR2, Decl(templateLiteralTypes1.ts, 114, 25))
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
|
||||
type TR3 = Trim<' xx '>; // 'xx'
|
||||
>TR3 : Symbol(TR3, Decl(templateLiteralTypes1.ts, 115, 25))
|
||||
>Trim : Symbol(Trim, Decl(templateLiteralTypes1.ts, 105, 32))
|
||||
|
||||
type Split<S extends string, D extends string> =
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 118, 11))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 118, 28))
|
||||
|
||||
string extends S ? string[] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 118, 11))
|
||||
|
||||
S extends '' ? [] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 118, 11))
|
||||
|
||||
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 118, 11))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 121, 22))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 118, 28))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 121, 36))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 121, 22))
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 121, 36))
|
||||
>D : Symbol(D, Decl(templateLiteralTypes1.ts, 118, 28))
|
||||
|
||||
[S];
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 118, 11))
|
||||
|
||||
type T40 = Split<'foo', '.'>; // ['foo']
|
||||
>T40 : Symbol(T40, Decl(templateLiteralTypes1.ts, 122, 8))
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
|
||||
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
|
||||
>T41 : Symbol(T41, Decl(templateLiteralTypes1.ts, 124, 29))
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
|
||||
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
|
||||
>T42 : Symbol(T42, Decl(templateLiteralTypes1.ts, 125, 37))
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
|
||||
type T43 = Split<any, '.'>; // string[]
|
||||
>T43 : Symbol(T43, Decl(templateLiteralTypes1.ts, 126, 32))
|
||||
>Split : Symbol(Split, Decl(templateLiteralTypes1.ts, 116, 28))
|
||||
|
||||
// Inference and property name paths
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 131, 27))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 131, 56))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 131, 27))
|
||||
>P2 : Symbol(P2, Decl(templateLiteralTypes1.ts, 131, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 131, 27))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 131, 56))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 131, 127))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>path : Symbol(path, Decl(templateLiteralTypes1.ts, 131, 134))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 131, 27))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 131, 56))
|
||||
>P2 : Symbol(P2, Decl(templateLiteralTypes1.ts, 131, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 131, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 131, 27))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 131, 56))
|
||||
>P2 : Symbol(P2, Decl(templateLiteralTypes1.ts, 131, 89))
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 132, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 132, 27))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 132, 25))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 132, 56))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 132, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 132, 27))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 132, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 132, 25))
|
||||
>path : Symbol(path, Decl(templateLiteralTypes1.ts, 132, 97))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 132, 27))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 132, 56))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 132, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 132, 27))
|
||||
>P1 : Symbol(P1, Decl(templateLiteralTypes1.ts, 132, 56))
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 133, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 133, 27))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 133, 25))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 133, 57))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 133, 25))
|
||||
>path : Symbol(path, Decl(templateLiteralTypes1.ts, 133, 64))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 133, 27))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 133, 25))
|
||||
>P0 : Symbol(P0, Decl(templateLiteralTypes1.ts, 133, 27))
|
||||
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 134, 25))
|
||||
>path : Symbol(path, Decl(templateLiteralTypes1.ts, 134, 37))
|
||||
|
||||
let p1 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a');
|
||||
>p1 : Symbol(p1, Decl(templateLiteralTypes1.ts, 136, 3))
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>a : Symbol(a, Decl(templateLiteralTypes1.ts, 136, 18))
|
||||
>b : Symbol(b, Decl(templateLiteralTypes1.ts, 136, 23))
|
||||
>c : Symbol(c, Decl(templateLiteralTypes1.ts, 136, 28))
|
||||
>d : Symbol(d, Decl(templateLiteralTypes1.ts, 136, 34))
|
||||
|
||||
let p2 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b');
|
||||
>p2 : Symbol(p2, Decl(templateLiteralTypes1.ts, 137, 3))
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>a : Symbol(a, Decl(templateLiteralTypes1.ts, 137, 18))
|
||||
>b : Symbol(b, Decl(templateLiteralTypes1.ts, 137, 23))
|
||||
>c : Symbol(c, Decl(templateLiteralTypes1.ts, 137, 28))
|
||||
>d : Symbol(d, Decl(templateLiteralTypes1.ts, 137, 34))
|
||||
|
||||
let p3 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d');
|
||||
>p3 : Symbol(p3, Decl(templateLiteralTypes1.ts, 138, 3))
|
||||
>getProp : Symbol(getProp, Decl(templateLiteralTypes1.ts, 127, 27), Decl(templateLiteralTypes1.ts, 131, 177), Decl(templateLiteralTypes1.ts, 132, 130), Decl(templateLiteralTypes1.ts, 133, 82))
|
||||
>a : Symbol(a, Decl(templateLiteralTypes1.ts, 138, 18))
|
||||
>b : Symbol(b, Decl(templateLiteralTypes1.ts, 138, 23))
|
||||
>c : Symbol(c, Decl(templateLiteralTypes1.ts, 138, 28))
|
||||
>d : Symbol(d, Decl(templateLiteralTypes1.ts, 138, 34))
|
||||
|
||||
type PropType<T, Path extends string> =
|
||||
>PropType : Symbol(PropType, Decl(templateLiteralTypes1.ts, 138, 69))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 140, 14))
|
||||
>Path : Symbol(Path, Decl(templateLiteralTypes1.ts, 140, 16))
|
||||
|
||||
string extends Path ? unknown :
|
||||
>Path : Symbol(Path, Decl(templateLiteralTypes1.ts, 140, 16))
|
||||
|
||||
Path extends keyof T ? T[Path] :
|
||||
>Path : Symbol(Path, Decl(templateLiteralTypes1.ts, 140, 16))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 140, 14))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 140, 14))
|
||||
>Path : Symbol(Path, Decl(templateLiteralTypes1.ts, 140, 16))
|
||||
|
||||
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
|
||||
>Path : Symbol(Path, Decl(templateLiteralTypes1.ts, 140, 16))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes1.ts, 143, 25))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 143, 36))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes1.ts, 143, 25))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 140, 14))
|
||||
>PropType : Symbol(PropType, Decl(templateLiteralTypes1.ts, 138, 69))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 140, 14))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes1.ts, 143, 25))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 143, 36))
|
||||
|
||||
unknown;
|
||||
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 146, 30))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 146, 32))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 146, 51))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 146, 30))
|
||||
>path : Symbol(path, Decl(templateLiteralTypes1.ts, 146, 58))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 146, 32))
|
||||
>PropType : Symbol(PropType, Decl(templateLiteralTypes1.ts, 138, 69))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 146, 30))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes1.ts, 146, 32))
|
||||
|
||||
declare const s: string;
|
||||
>s : Symbol(s, Decl(templateLiteralTypes1.ts, 147, 13))
|
||||
|
||||
const obj = { a: { b: {c: 42, d: 'hello' }}};
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
>a : Symbol(a, Decl(templateLiteralTypes1.ts, 149, 13))
|
||||
>b : Symbol(b, Decl(templateLiteralTypes1.ts, 149, 18))
|
||||
>c : Symbol(c, Decl(templateLiteralTypes1.ts, 149, 23))
|
||||
>d : Symbol(d, Decl(templateLiteralTypes1.ts, 149, 29))
|
||||
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
|
||||
getPropValue(obj, s); // unknown
|
||||
>getPropValue : Symbol(getPropValue, Decl(templateLiteralTypes1.ts, 144, 12))
|
||||
>obj : Symbol(obj, Decl(templateLiteralTypes1.ts, 149, 5))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes1.ts, 147, 13))
|
||||
|
||||
// Infer type variables in template literals have string constraint
|
||||
|
||||
type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
>S1 : Symbol(S1, Decl(templateLiteralTypes1.ts, 155, 21))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 159, 8))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes1.ts, 159, 8))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 159, 34))
|
||||
>S2 : Symbol(S2, Decl(templateLiteralTypes1.ts, 159, 58))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes1.ts, 159, 34))
|
||||
|
||||
type S2<S extends string> = S;
|
||||
>S2 : Symbol(S2, Decl(templateLiteralTypes1.ts, 159, 58))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 160, 8))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 160, 8))
|
||||
|
||||
// Batched single character inferences for lower recursion depth
|
||||
|
||||
type Chars<S extends string> =
|
||||
>Chars : Symbol(Chars, Decl(templateLiteralTypes1.ts, 160, 30))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 164, 11))
|
||||
|
||||
string extends S ? string[] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 164, 11))
|
||||
|
||||
S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 164, 11))
|
||||
>C0 : Symbol(C0, Decl(templateLiteralTypes1.ts, 166, 22))
|
||||
>C1 : Symbol(C1, Decl(templateLiteralTypes1.ts, 166, 33))
|
||||
>C2 : Symbol(C2, Decl(templateLiteralTypes1.ts, 166, 44))
|
||||
>C3 : Symbol(C3, Decl(templateLiteralTypes1.ts, 166, 55))
|
||||
>C4 : Symbol(C4, Decl(templateLiteralTypes1.ts, 166, 66))
|
||||
>C5 : Symbol(C5, Decl(templateLiteralTypes1.ts, 166, 77))
|
||||
>C6 : Symbol(C6, Decl(templateLiteralTypes1.ts, 166, 88))
|
||||
>C7 : Symbol(C7, Decl(templateLiteralTypes1.ts, 166, 99))
|
||||
>C8 : Symbol(C8, Decl(templateLiteralTypes1.ts, 166, 110))
|
||||
>C9 : Symbol(C9, Decl(templateLiteralTypes1.ts, 166, 121))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 166, 132))
|
||||
>C0 : Symbol(C0, Decl(templateLiteralTypes1.ts, 166, 22))
|
||||
>C1 : Symbol(C1, Decl(templateLiteralTypes1.ts, 166, 33))
|
||||
>C2 : Symbol(C2, Decl(templateLiteralTypes1.ts, 166, 44))
|
||||
>C3 : Symbol(C3, Decl(templateLiteralTypes1.ts, 166, 55))
|
||||
>C4 : Symbol(C4, Decl(templateLiteralTypes1.ts, 166, 66))
|
||||
>C5 : Symbol(C5, Decl(templateLiteralTypes1.ts, 166, 77))
|
||||
>C6 : Symbol(C6, Decl(templateLiteralTypes1.ts, 166, 88))
|
||||
>C7 : Symbol(C7, Decl(templateLiteralTypes1.ts, 166, 99))
|
||||
>C8 : Symbol(C8, Decl(templateLiteralTypes1.ts, 166, 110))
|
||||
>C9 : Symbol(C9, Decl(templateLiteralTypes1.ts, 166, 121))
|
||||
>Chars : Symbol(Chars, Decl(templateLiteralTypes1.ts, 160, 30))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 166, 132))
|
||||
|
||||
S extends `${infer C}${infer R}` ? [C, ...Chars<R>] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 164, 11))
|
||||
>C : Symbol(C, Decl(templateLiteralTypes1.ts, 167, 22))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 167, 32))
|
||||
>C : Symbol(C, Decl(templateLiteralTypes1.ts, 167, 22))
|
||||
>Chars : Symbol(Chars, Decl(templateLiteralTypes1.ts, 160, 30))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes1.ts, 167, 32))
|
||||
|
||||
S extends '' ? [] :
|
||||
>S : Symbol(S, Decl(templateLiteralTypes1.ts, 164, 11))
|
||||
|
||||
never;
|
||||
|
||||
type L1 = Chars<'FooBarBazThisIsALongerString'>; // ['F', 'o', 'o', 'B', 'a', 'r', ...]
|
||||
>L1 : Symbol(L1, Decl(templateLiteralTypes1.ts, 169, 10))
|
||||
>Chars : Symbol(Chars, Decl(templateLiteralTypes1.ts, 160, 30))
|
||||
|
||||
// Cross product unions limited to 100,000 constituents
|
||||
|
||||
type A = any;
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U1 = {a1:A} | {b1:A} | {c1:A} | {d1:A} | {e1:A} | {f1:A} | {g1:A} | {h1:A} | {i1:A} | {j1:A};
|
||||
>U1 : Symbol(U1, Decl(templateLiteralTypes1.ts, 175, 13))
|
||||
>a1 : Symbol(a1, Decl(templateLiteralTypes1.ts, 177, 11))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>b1 : Symbol(b1, Decl(templateLiteralTypes1.ts, 177, 20))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>c1 : Symbol(c1, Decl(templateLiteralTypes1.ts, 177, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>d1 : Symbol(d1, Decl(templateLiteralTypes1.ts, 177, 38))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>e1 : Symbol(e1, Decl(templateLiteralTypes1.ts, 177, 47))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>f1 : Symbol(f1, Decl(templateLiteralTypes1.ts, 177, 56))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>g1 : Symbol(g1, Decl(templateLiteralTypes1.ts, 177, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>h1 : Symbol(h1, Decl(templateLiteralTypes1.ts, 177, 74))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>i1 : Symbol(i1, Decl(templateLiteralTypes1.ts, 177, 83))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>j1 : Symbol(j1, Decl(templateLiteralTypes1.ts, 177, 92))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U2 = {a2:A} | {b2:A} | {c2:A} | {d2:A} | {e2:A} | {f2:A} | {g2:A} | {h2:A} | {i2:A} | {j2:A};
|
||||
>U2 : Symbol(U2, Decl(templateLiteralTypes1.ts, 177, 98))
|
||||
>a2 : Symbol(a2, Decl(templateLiteralTypes1.ts, 178, 11))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>b2 : Symbol(b2, Decl(templateLiteralTypes1.ts, 178, 20))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>c2 : Symbol(c2, Decl(templateLiteralTypes1.ts, 178, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>d2 : Symbol(d2, Decl(templateLiteralTypes1.ts, 178, 38))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>e2 : Symbol(e2, Decl(templateLiteralTypes1.ts, 178, 47))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>f2 : Symbol(f2, Decl(templateLiteralTypes1.ts, 178, 56))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>g2 : Symbol(g2, Decl(templateLiteralTypes1.ts, 178, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>h2 : Symbol(h2, Decl(templateLiteralTypes1.ts, 178, 74))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>i2 : Symbol(i2, Decl(templateLiteralTypes1.ts, 178, 83))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>j2 : Symbol(j2, Decl(templateLiteralTypes1.ts, 178, 92))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U3 = {a3:A} | {b3:A} | {c3:A} | {d3:A} | {e3:A} | {f3:A} | {g3:A} | {h3:A} | {i3:A} | {j3:A};
|
||||
>U3 : Symbol(U3, Decl(templateLiteralTypes1.ts, 178, 98))
|
||||
>a3 : Symbol(a3, Decl(templateLiteralTypes1.ts, 179, 11))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>b3 : Symbol(b3, Decl(templateLiteralTypes1.ts, 179, 20))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>c3 : Symbol(c3, Decl(templateLiteralTypes1.ts, 179, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>d3 : Symbol(d3, Decl(templateLiteralTypes1.ts, 179, 38))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>e3 : Symbol(e3, Decl(templateLiteralTypes1.ts, 179, 47))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>f3 : Symbol(f3, Decl(templateLiteralTypes1.ts, 179, 56))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>g3 : Symbol(g3, Decl(templateLiteralTypes1.ts, 179, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>h3 : Symbol(h3, Decl(templateLiteralTypes1.ts, 179, 74))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>i3 : Symbol(i3, Decl(templateLiteralTypes1.ts, 179, 83))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>j3 : Symbol(j3, Decl(templateLiteralTypes1.ts, 179, 92))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U4 = {a4:A} | {b4:A} | {c4:A} | {d4:A} | {e4:A} | {f4:A} | {g4:A} | {h4:A} | {i4:A} | {j4:A};
|
||||
>U4 : Symbol(U4, Decl(templateLiteralTypes1.ts, 179, 98))
|
||||
>a4 : Symbol(a4, Decl(templateLiteralTypes1.ts, 180, 11))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>b4 : Symbol(b4, Decl(templateLiteralTypes1.ts, 180, 20))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>c4 : Symbol(c4, Decl(templateLiteralTypes1.ts, 180, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>d4 : Symbol(d4, Decl(templateLiteralTypes1.ts, 180, 38))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>e4 : Symbol(e4, Decl(templateLiteralTypes1.ts, 180, 47))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>f4 : Symbol(f4, Decl(templateLiteralTypes1.ts, 180, 56))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>g4 : Symbol(g4, Decl(templateLiteralTypes1.ts, 180, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>h4 : Symbol(h4, Decl(templateLiteralTypes1.ts, 180, 74))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>i4 : Symbol(i4, Decl(templateLiteralTypes1.ts, 180, 83))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>j4 : Symbol(j4, Decl(templateLiteralTypes1.ts, 180, 92))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U5 = {a5:A} | {b5:A} | {c5:A} | {d5:A} | {e5:A} | {f5:A} | {g5:A} | {h5:A} | {i5:A} | {j5:A};
|
||||
>U5 : Symbol(U5, Decl(templateLiteralTypes1.ts, 180, 98))
|
||||
>a5 : Symbol(a5, Decl(templateLiteralTypes1.ts, 181, 11))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>b5 : Symbol(b5, Decl(templateLiteralTypes1.ts, 181, 20))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>c5 : Symbol(c5, Decl(templateLiteralTypes1.ts, 181, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>d5 : Symbol(d5, Decl(templateLiteralTypes1.ts, 181, 38))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>e5 : Symbol(e5, Decl(templateLiteralTypes1.ts, 181, 47))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>f5 : Symbol(f5, Decl(templateLiteralTypes1.ts, 181, 56))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>g5 : Symbol(g5, Decl(templateLiteralTypes1.ts, 181, 65))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>h5 : Symbol(h5, Decl(templateLiteralTypes1.ts, 181, 74))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>i5 : Symbol(i5, Decl(templateLiteralTypes1.ts, 181, 83))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
>j5 : Symbol(j5, Decl(templateLiteralTypes1.ts, 181, 92))
|
||||
>A : Symbol(A, Decl(templateLiteralTypes1.ts, 171, 48))
|
||||
|
||||
type U100000 = U1 & U2 & U3 & U4 & U5; // Error
|
||||
>U100000 : Symbol(U100000, Decl(templateLiteralTypes1.ts, 181, 98))
|
||||
>U1 : Symbol(U1, Decl(templateLiteralTypes1.ts, 175, 13))
|
||||
>U2 : Symbol(U2, Decl(templateLiteralTypes1.ts, 177, 98))
|
||||
>U3 : Symbol(U3, Decl(templateLiteralTypes1.ts, 178, 98))
|
||||
>U4 : Symbol(U4, Decl(templateLiteralTypes1.ts, 179, 98))
|
||||
>U5 : Symbol(U5, Decl(templateLiteralTypes1.ts, 180, 98))
|
||||
|
||||
type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
|
||||
type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; // Error
|
||||
>D100000 : Symbol(D100000, Decl(templateLiteralTypes1.ts, 185, 52))
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
>Digits : Symbol(Digits, Decl(templateLiteralTypes1.ts, 183, 38))
|
||||
|
||||
type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
|
||||
type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; // Error
|
||||
>T100000 : Symbol(T100000, Decl(templateLiteralTypes1.ts, 189, 73))
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
>TDigits : Symbol(TDigits, Decl(templateLiteralTypes1.ts, 187, 63))
|
||||
|
||||
496
tests/baselines/reference/templateLiteralTypes1.types
Normal file
496
tests/baselines/reference/templateLiteralTypes1.types
Normal file
@ -0,0 +1,496 @@
|
||||
=== tests/cases/conformance/types/literal/templateLiteralTypes1.ts ===
|
||||
// Template types example from #12754
|
||||
|
||||
const createScopedActionType = <S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}`;
|
||||
>createScopedActionType : <S extends string>(scope: S) => <T extends string>(type: T) => `${S}/${T}`
|
||||
><S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}` : <S extends string>(scope: S) => <T extends string>(type: T) => `${S}/${T}`
|
||||
>scope : S
|
||||
><T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}` : <T extends string>(type: T) => `${S}/${T}`
|
||||
>type : T
|
||||
>`${scope}/${type}` as `${S}/${T}` : `${S}/${T}`
|
||||
>`${scope}/${type}` : string
|
||||
>scope : S
|
||||
>type : T
|
||||
|
||||
const createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
>createActionInMyScope : <T extends string>(type: T) => `MyScope/${T}`
|
||||
>createScopedActionType("MyScope") : <T extends string>(type: T) => `MyScope/${T}`
|
||||
>createScopedActionType : <S extends string>(scope: S) => <T extends string>(type: T) => `${S}/${T}`
|
||||
>"MyScope" : "MyScope"
|
||||
|
||||
const MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
>MY_ACTION : "MyScope/MY_ACTION"
|
||||
>createActionInMyScope("MY_ACTION") : "MyScope/MY_ACTION"
|
||||
>createActionInMyScope : <T extends string>(type: T) => `MyScope/${T}`
|
||||
>"MY_ACTION" : "MY_ACTION"
|
||||
|
||||
// Union types are distributed over template types
|
||||
|
||||
type EventName<S extends string> = `${S}Changed`;
|
||||
>EventName : `${S}Changed`
|
||||
|
||||
type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
>EN1 : "FooChanged" | "BarChanged" | "BazChanged"
|
||||
|
||||
type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
>Loc : "top-left" | "top-center" | "top-right" | "middle-left" | "middle-center" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right"
|
||||
|
||||
// Primitive literal types can be spread into templates
|
||||
|
||||
type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
>ToString : `${T}`
|
||||
|
||||
type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
>TS1 : "abc" | "true" | "42" | "-1234"
|
||||
>true : true
|
||||
>-1234n : -1234n
|
||||
>1234n : 1234n
|
||||
|
||||
// Casing modifiers
|
||||
|
||||
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
>Cases : `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`
|
||||
|
||||
type TCA1 = Cases<'bar'>; // 'BAR bar Bar bar'
|
||||
>TCA1 : "BAR bar Bar bar"
|
||||
|
||||
type TCA2 = Cases<'BAR'>; // 'BAR bar BAR bAR'
|
||||
>TCA2 : "BAR bar BAR bAR"
|
||||
|
||||
// Assignability
|
||||
|
||||
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
|
||||
>test : <T extends "bar" | "foo">(name: `get${capitalize T}`) => void
|
||||
>name : `get${capitalize T}`
|
||||
|
||||
let s1: string = name;
|
||||
>s1 : string
|
||||
>name : `get${capitalize T}`
|
||||
|
||||
let s2: 'getFoo' | 'getBar' = name;
|
||||
>s2 : "getFoo" | "getBar"
|
||||
>name : `get${capitalize T}`
|
||||
}
|
||||
|
||||
function fa1<T>(x: T, y: { [P in keyof T]: T[P] }, z: { [P in keyof T & string as `p_${P}`]: T[P] }) {
|
||||
>fa1 : <T>(x: T, y: { [P in keyof T]: T[P]; }, z: { [P in keyof T & string as `p_${P}`]: T[P]; }) => void
|
||||
>x : T
|
||||
>y : { [P in keyof T]: T[P]; }
|
||||
>z : { [P in keyof T & string as `p_${P}`]: T[P]; }
|
||||
|
||||
y = x;
|
||||
>y = x : T
|
||||
>y : { [P in keyof T]: T[P]; }
|
||||
>x : T
|
||||
|
||||
z = x; // Error
|
||||
>z = x : T
|
||||
>z : { [P in keyof T & string as `p_${P}`]: T[P]; }
|
||||
>x : T
|
||||
}
|
||||
|
||||
function fa2<T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T }, y: { [Q in A as `p_${Q}`]: U }) {
|
||||
>fa2 : <T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T; }, y: { [Q in A as `p_${Q}`]: U; }) => void
|
||||
>x : { [P in B as `p_${P}`]: T; }
|
||||
>y : { [Q in A as `p_${Q}`]: U; }
|
||||
|
||||
x = y;
|
||||
>x = y : { [Q in A as `p_${Q}`]: U; }
|
||||
>x : { [P in B as `p_${P}`]: T; }
|
||||
>y : { [Q in A as `p_${Q}`]: U; }
|
||||
|
||||
y = x; // Error
|
||||
>y = x : { [P in B as `p_${P}`]: T; }
|
||||
>y : { [Q in A as `p_${Q}`]: U; }
|
||||
>x : { [P in B as `p_${P}`]: T; }
|
||||
}
|
||||
|
||||
// String transformations using recursive conditional types
|
||||
|
||||
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
|
||||
>Join : Join<T, D>
|
||||
|
||||
T extends [] ? '' :
|
||||
T extends [unknown] ? `${T[0]}` :
|
||||
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
|
||||
string;
|
||||
|
||||
type TJ1 = Join<[1, 2, 3, 4], '.'>
|
||||
>TJ1 : "1.2.3.4"
|
||||
|
||||
type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
>TJ2 : "foo-bar-baz"
|
||||
|
||||
type TJ3 = Join<[], '.'>
|
||||
>TJ3 : ""
|
||||
|
||||
// Inference based on delimiters
|
||||
|
||||
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
>MatchPair : MatchPair<S>
|
||||
|
||||
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
|
||||
>T20 : ["1", "2"]
|
||||
|
||||
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
|
||||
>T21 : ["foo", "bar"]
|
||||
|
||||
type T22 = MatchPair<' [1,2]'>; // unknown
|
||||
>T22 : unknown
|
||||
|
||||
type T23 = MatchPair<'[123]'>; // unknown
|
||||
>T23 : unknown
|
||||
|
||||
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
|
||||
>T24 : ["1", "2,3,4"]
|
||||
|
||||
type SnakeToCamelCase<S extends string> =
|
||||
>SnakeToCamelCase : SnakeToCamelCase<S>
|
||||
|
||||
S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${lowercase T}` :
|
||||
SnakeToPascalCase<S>;
|
||||
|
||||
type SnakeToPascalCase<S extends string> =
|
||||
>SnakeToPascalCase : SnakeToPascalCase<S>
|
||||
|
||||
string extends S ? string :
|
||||
S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${capitalize `${lowercase T}`}` :
|
||||
never;
|
||||
|
||||
type RR0 = SnakeToPascalCase<'hello_world_foo'>; // 'HelloWorldFoo'
|
||||
>RR0 : "HelloWorldFoo"
|
||||
|
||||
type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; // 'FooBarBaz'
|
||||
>RR1 : "FooBarBaz"
|
||||
|
||||
type RR2 = SnakeToCamelCase<'hello_world_foo'>; // 'helloWorldFoo'
|
||||
>RR2 : "helloWorldFoo"
|
||||
|
||||
type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; // 'fooBarBaz'
|
||||
>RR3 : "fooBarBaz"
|
||||
|
||||
// Single character inference
|
||||
|
||||
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
>FirstTwoAndRest : FirstTwoAndRest<S>
|
||||
|
||||
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
|
||||
>T25 : ["ab", "cde"]
|
||||
|
||||
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
|
||||
>T26 : ["ab", ""]
|
||||
|
||||
type T27 = FirstTwoAndRest<'a'>; // unknown
|
||||
>T27 : unknown
|
||||
|
||||
type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
>Capitalize : Capitalize<S>
|
||||
|
||||
type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
>Uncapitalize : Uncapitalize<S>
|
||||
|
||||
type TC1 = Capitalize<'foo'>; // 'Foo'
|
||||
>TC1 : "Foo"
|
||||
|
||||
type TC2 = Uncapitalize<'Foo'>; // 'foo'
|
||||
>TC2 : "foo"
|
||||
|
||||
type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |'8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
>HexDigit : HexDigit
|
||||
|
||||
type HexColor<S extends string> =
|
||||
>HexColor : HexColor<S>
|
||||
|
||||
S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ?
|
||||
[R1, R2, G1, G2, B1, B2] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ?
|
||||
S :
|
||||
never :
|
||||
never;
|
||||
|
||||
type TH1 = HexColor<'#8080FF'>; // '#8080FF'
|
||||
>TH1 : "#8080FF"
|
||||
|
||||
type TH2 = HexColor<'#80c0ff'>; // '#80c0ff'
|
||||
>TH2 : "#80c0ff"
|
||||
|
||||
type TH3 = HexColor<'#8080F'>; // never
|
||||
>TH3 : never
|
||||
|
||||
type TH4 = HexColor<'#8080FFF'>; // never
|
||||
>TH4 : never
|
||||
|
||||
// Recursive inference
|
||||
|
||||
type Trim<S extends string> =
|
||||
>Trim : Trim<S>
|
||||
|
||||
S extends ` ${infer T}` ? Trim<T> :
|
||||
S extends `${infer T} ` ? Trim<T> :
|
||||
S;
|
||||
|
||||
type TR1 = Trim<'xx '>; // 'xx'
|
||||
>TR1 : "xx"
|
||||
|
||||
type TR2 = Trim<' xx'>; // 'xx'
|
||||
>TR2 : "xx"
|
||||
|
||||
type TR3 = Trim<' xx '>; // 'xx'
|
||||
>TR3 : "xx"
|
||||
|
||||
type Split<S extends string, D extends string> =
|
||||
>Split : Split<S, D>
|
||||
|
||||
string extends S ? string[] :
|
||||
S extends '' ? [] :
|
||||
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
|
||||
[S];
|
||||
|
||||
type T40 = Split<'foo', '.'>; // ['foo']
|
||||
>T40 : ["foo"]
|
||||
|
||||
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
|
||||
>T41 : ["foo", "bar", "baz"]
|
||||
|
||||
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
|
||||
>T42 : ["f", "o", "o", ".", "b", "a", "r"]
|
||||
|
||||
type T43 = Split<any, '.'>; // string[]
|
||||
>T43 : string[]
|
||||
|
||||
// Inference and property name paths
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>obj : T
|
||||
>path : `${P0}.${P1}.${P2}`
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>obj : T
|
||||
>path : `${P0}.${P1}`
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>obj : T
|
||||
>path : P0
|
||||
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>obj : object
|
||||
>path : string
|
||||
|
||||
let p1 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a');
|
||||
>p1 : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a') : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} as const : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>a : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>{ b: {c: 42, d: 'hello' }} : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>b : { readonly c: 42; readonly d: "hello"; }
|
||||
>{c: 42, d: 'hello' } : { readonly c: 42; readonly d: "hello"; }
|
||||
>c : 42
|
||||
>42 : 42
|
||||
>d : "hello"
|
||||
>'hello' : "hello"
|
||||
>'a' : "a"
|
||||
|
||||
let p2 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b');
|
||||
>p2 : { readonly c: 42; readonly d: "hello"; }
|
||||
>getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b') : { readonly c: 42; readonly d: "hello"; }
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} as const : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>a : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>{ b: {c: 42, d: 'hello' }} : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>b : { readonly c: 42; readonly d: "hello"; }
|
||||
>{c: 42, d: 'hello' } : { readonly c: 42; readonly d: "hello"; }
|
||||
>c : 42
|
||||
>42 : 42
|
||||
>d : "hello"
|
||||
>'hello' : "hello"
|
||||
>'a.b' : "a.b"
|
||||
|
||||
let p3 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d');
|
||||
>p3 : "hello"
|
||||
>getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d') : "hello"
|
||||
>getProp : { <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; <T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1]; <T, P0 extends keyof T & string>(obj: T, path: P0): T[P0]; (obj: object, path: string): unknown; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} as const : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} : { readonly a: { readonly b: { readonly c: 42; readonly d: "hello"; }; }; }
|
||||
>a : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>{ b: {c: 42, d: 'hello' }} : { readonly b: { readonly c: 42; readonly d: "hello"; }; }
|
||||
>b : { readonly c: 42; readonly d: "hello"; }
|
||||
>{c: 42, d: 'hello' } : { readonly c: 42; readonly d: "hello"; }
|
||||
>c : 42
|
||||
>42 : 42
|
||||
>d : "hello"
|
||||
>'hello' : "hello"
|
||||
>'a.b.d' : "a.b.d"
|
||||
|
||||
type PropType<T, Path extends string> =
|
||||
>PropType : PropType<T, Path>
|
||||
|
||||
string extends Path ? unknown :
|
||||
Path extends keyof T ? T[Path] :
|
||||
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
|
||||
unknown;
|
||||
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : T
|
||||
>path : P
|
||||
|
||||
declare const s: string;
|
||||
>s : string
|
||||
|
||||
const obj = { a: { b: {c: 42, d: 'hello' }}};
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>{ a: { b: {c: 42, d: 'hello' }}} : { a: { b: { c: number; d: string; }; }; }
|
||||
>a : { b: { c: number; d: string; }; }
|
||||
>{ b: {c: 42, d: 'hello' }} : { b: { c: number; d: string; }; }
|
||||
>b : { c: number; d: string; }
|
||||
>{c: 42, d: 'hello' } : { c: number; d: string; }
|
||||
>c : number
|
||||
>42 : 42
|
||||
>d : string
|
||||
>'hello' : "hello"
|
||||
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
>getPropValue(obj, 'a') : { b: { c: number; d: string; }; }
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>'a' : "a"
|
||||
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
>getPropValue(obj, 'a.b') : { c: number; d: string; }
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>'a.b' : "a.b"
|
||||
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
>getPropValue(obj, 'a.b.d') : string
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>'a.b.d' : "a.b.d"
|
||||
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
>getPropValue(obj, 'a.b.x') : unknown
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>'a.b.x' : "a.b.x"
|
||||
|
||||
getPropValue(obj, s); // unknown
|
||||
>getPropValue(obj, s) : unknown
|
||||
>getPropValue : <T, P extends string>(obj: T, path: P) => PropType<T, P>
|
||||
>obj : { a: { b: { c: number; d: string; }; }; }
|
||||
>s : string
|
||||
|
||||
// Infer type variables in template literals have string constraint
|
||||
|
||||
type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
>S1 : S1<T>
|
||||
|
||||
type S2<S extends string> = S;
|
||||
>S2 : S
|
||||
|
||||
// Batched single character inferences for lower recursion depth
|
||||
|
||||
type Chars<S extends string> =
|
||||
>Chars : Chars<S>
|
||||
|
||||
string extends S ? string[] :
|
||||
S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] :
|
||||
S extends `${infer C}${infer R}` ? [C, ...Chars<R>] :
|
||||
S extends '' ? [] :
|
||||
never;
|
||||
|
||||
type L1 = Chars<'FooBarBazThisIsALongerString'>; // ['F', 'o', 'o', 'B', 'a', 'r', ...]
|
||||
>L1 : ["F", "o", "o", "B", "a", "r", "B", "a", "z", "T", "h", "i", "s", "I", "s", "A", "L", "o", "n", "g", "e", "r", "S", "t", "r", "i", "n", "g"]
|
||||
|
||||
// Cross product unions limited to 100,000 constituents
|
||||
|
||||
type A = any;
|
||||
>A : any
|
||||
|
||||
type U1 = {a1:A} | {b1:A} | {c1:A} | {d1:A} | {e1:A} | {f1:A} | {g1:A} | {h1:A} | {i1:A} | {j1:A};
|
||||
>U1 : U1
|
||||
>a1 : any
|
||||
>b1 : any
|
||||
>c1 : any
|
||||
>d1 : any
|
||||
>e1 : any
|
||||
>f1 : any
|
||||
>g1 : any
|
||||
>h1 : any
|
||||
>i1 : any
|
||||
>j1 : any
|
||||
|
||||
type U2 = {a2:A} | {b2:A} | {c2:A} | {d2:A} | {e2:A} | {f2:A} | {g2:A} | {h2:A} | {i2:A} | {j2:A};
|
||||
>U2 : U2
|
||||
>a2 : any
|
||||
>b2 : any
|
||||
>c2 : any
|
||||
>d2 : any
|
||||
>e2 : any
|
||||
>f2 : any
|
||||
>g2 : any
|
||||
>h2 : any
|
||||
>i2 : any
|
||||
>j2 : any
|
||||
|
||||
type U3 = {a3:A} | {b3:A} | {c3:A} | {d3:A} | {e3:A} | {f3:A} | {g3:A} | {h3:A} | {i3:A} | {j3:A};
|
||||
>U3 : U3
|
||||
>a3 : any
|
||||
>b3 : any
|
||||
>c3 : any
|
||||
>d3 : any
|
||||
>e3 : any
|
||||
>f3 : any
|
||||
>g3 : any
|
||||
>h3 : any
|
||||
>i3 : any
|
||||
>j3 : any
|
||||
|
||||
type U4 = {a4:A} | {b4:A} | {c4:A} | {d4:A} | {e4:A} | {f4:A} | {g4:A} | {h4:A} | {i4:A} | {j4:A};
|
||||
>U4 : U4
|
||||
>a4 : any
|
||||
>b4 : any
|
||||
>c4 : any
|
||||
>d4 : any
|
||||
>e4 : any
|
||||
>f4 : any
|
||||
>g4 : any
|
||||
>h4 : any
|
||||
>i4 : any
|
||||
>j4 : any
|
||||
|
||||
type U5 = {a5:A} | {b5:A} | {c5:A} | {d5:A} | {e5:A} | {f5:A} | {g5:A} | {h5:A} | {i5:A} | {j5:A};
|
||||
>U5 : U5
|
||||
>a5 : any
|
||||
>b5 : any
|
||||
>c5 : any
|
||||
>d5 : any
|
||||
>e5 : any
|
||||
>f5 : any
|
||||
>g5 : any
|
||||
>h5 : any
|
||||
>i5 : any
|
||||
>j5 : any
|
||||
|
||||
type U100000 = U1 & U2 & U3 & U4 & U5; // Error
|
||||
>U100000 : any
|
||||
|
||||
type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
>Digits : Digits
|
||||
|
||||
type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; // Error
|
||||
>D100000 : any
|
||||
|
||||
type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
>TDigits : TDigits
|
||||
|
||||
type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; // Error
|
||||
>T100000 : any
|
||||
|
||||
@ -1,20 +1,10 @@
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts(1,10): error TS2394: This overload signature is not compatible with its implementation signature.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts(1,12): error TS1138: Parameter declaration expected.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts(1,19): error TS1005: ';' expected.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts(1,12): error TS1003: Identifier expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts (4 errors) ====
|
||||
==== tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts (1 errors) ====
|
||||
function f(`hello`);
|
||||
~
|
||||
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
~
|
||||
!!! error TS2394: This overload signature is not compatible with its implementation signature.
|
||||
!!! related TS2750 tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts:3:10: The implementation signature is declared here.
|
||||
~~~~~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
!!! error TS1003: Identifier expected.
|
||||
function f(x: string);
|
||||
function f(x: string) {
|
||||
return x;
|
||||
|
||||
@ -6,9 +6,6 @@ function f(x: string) {
|
||||
}
|
||||
|
||||
//// [templateStringInFunctionParameterType.js]
|
||||
function f() { }
|
||||
"hello";
|
||||
;
|
||||
function f(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
=== tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts ===
|
||||
function f(`hello`);
|
||||
>f : Symbol(f, Decl(templateStringInFunctionParameterType.ts, 0, 0), Decl(templateStringInFunctionParameterType.ts, 0, 20), Decl(templateStringInFunctionParameterType.ts, 1, 22))
|
||||
> : Symbol((Missing), Decl(templateStringInFunctionParameterType.ts, 0, 11))
|
||||
|
||||
function f(x: string);
|
||||
>f : Symbol(f, Decl(templateStringInFunctionParameterType.ts, 0, 0), Decl(templateStringInFunctionParameterType.ts, 0, 20), Decl(templateStringInFunctionParameterType.ts, 1, 22))
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
=== tests/cases/conformance/es6/templates/templateStringInFunctionParameterType.ts ===
|
||||
function f(`hello`);
|
||||
>f : { (): any; (x: string): any; }
|
||||
>`hello` : "hello"
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
> : any
|
||||
|
||||
function f(x: string);
|
||||
>f : { (): any; (x: string): any; }
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
>x : string
|
||||
|
||||
function f(x: string) {
|
||||
>f : { (): any; (x: string): any; }
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
>x : string
|
||||
|
||||
return x;
|
||||
|
||||
@ -1,20 +1,10 @@
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts(1,10): error TS2394: This overload signature is not compatible with its implementation signature.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts(1,12): error TS1138: Parameter declaration expected.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts(1,19): error TS1005: ';' expected.
|
||||
tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts(1,12): error TS1003: Identifier expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts (4 errors) ====
|
||||
==== tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts (1 errors) ====
|
||||
function f(`hello`);
|
||||
~
|
||||
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
~
|
||||
!!! error TS2394: This overload signature is not compatible with its implementation signature.
|
||||
!!! related TS2750 tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts:3:10: The implementation signature is declared here.
|
||||
~~~~~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
!!! error TS1003: Identifier expected.
|
||||
function f(x: string);
|
||||
function f(x: string) {
|
||||
return x;
|
||||
|
||||
@ -6,9 +6,6 @@ function f(x: string) {
|
||||
}
|
||||
|
||||
//// [templateStringInFunctionParameterTypeES6.js]
|
||||
function f() { }
|
||||
`hello`;
|
||||
;
|
||||
function f(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
=== tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts ===
|
||||
function f(`hello`);
|
||||
>f : Symbol(f, Decl(templateStringInFunctionParameterTypeES6.ts, 0, 0), Decl(templateStringInFunctionParameterTypeES6.ts, 0, 20), Decl(templateStringInFunctionParameterTypeES6.ts, 1, 22))
|
||||
> : Symbol((Missing), Decl(templateStringInFunctionParameterTypeES6.ts, 0, 11))
|
||||
|
||||
function f(x: string);
|
||||
>f : Symbol(f, Decl(templateStringInFunctionParameterTypeES6.ts, 0, 0), Decl(templateStringInFunctionParameterTypeES6.ts, 0, 20), Decl(templateStringInFunctionParameterTypeES6.ts, 1, 22))
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
=== tests/cases/conformance/es6/templates/templateStringInFunctionParameterTypeES6.ts ===
|
||||
function f(`hello`);
|
||||
>f : { (): any; (x: string): any; }
|
||||
>`hello` : "hello"
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
> : any
|
||||
|
||||
function f(x: string);
|
||||
>f : { (): any; (x: string): any; }
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
>x : string
|
||||
|
||||
function f(x: string) {
|
||||
>f : { (): any; (x: string): any; }
|
||||
>f : { (: any): any; (x: string): any; }
|
||||
>x : string
|
||||
|
||||
return x;
|
||||
|
||||
@ -72,13 +72,13 @@ var x7: T7;
|
||||
>x7 : C7
|
||||
|
||||
type T8 = string | boolean;
|
||||
>T8 : string | boolean
|
||||
>T8 : T8
|
||||
|
||||
var x8: string | boolean;
|
||||
>x8 : string | boolean
|
||||
>x8 : T8
|
||||
|
||||
var x8: T8;
|
||||
>x8 : string | boolean
|
||||
>x8 : T8
|
||||
|
||||
type T9 = () => string;
|
||||
>T9 : T9
|
||||
|
||||
@ -28,10 +28,10 @@ export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
|
||||
// Repro from #38102
|
||||
|
||||
export type TypedArray = Int32Array | Uint8Array;
|
||||
>TypedArray : Int32Array | Uint8Array
|
||||
>TypedArray : TypedArray
|
||||
|
||||
export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
|
||||
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
|
||||
>isTypedArray : (a: {}) => a is TypedArray
|
||||
>a : {}
|
||||
|
||||
return a instanceof Int32Array || a instanceof Uint8Array;
|
||||
@ -50,7 +50,7 @@ export function flatten<T extends number|TypedArray>(arr: T) {
|
||||
|
||||
if (isTypedArray(arr)) {
|
||||
>isTypedArray(arr) : boolean
|
||||
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
|
||||
>isTypedArray : (a: {}) => a is TypedArray
|
||||
>arr : T
|
||||
|
||||
arr[1];
|
||||
|
||||
195
tests/cases/conformance/types/literal/templateLiteralTypes1.ts
Normal file
195
tests/cases/conformance/types/literal/templateLiteralTypes1.ts
Normal file
@ -0,0 +1,195 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Template types example from #12754
|
||||
|
||||
const createScopedActionType = <S extends string>(scope: S) => <T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}`;
|
||||
const createActionInMyScope = createScopedActionType("MyScope"); // <T extends string>(type: T) => `MyScope/${T}`
|
||||
const MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION'
|
||||
|
||||
// Union types are distributed over template types
|
||||
|
||||
type EventName<S extends string> = `${S}Changed`;
|
||||
type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>;
|
||||
type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`;
|
||||
|
||||
// Primitive literal types can be spread into templates
|
||||
|
||||
type ToString<T extends string | number | boolean | bigint> = `${T}`;
|
||||
type TS1 = ToString<'abc' | 42 | true | -1234n>;
|
||||
|
||||
// Casing modifiers
|
||||
|
||||
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
|
||||
|
||||
type TCA1 = Cases<'bar'>; // 'BAR bar Bar bar'
|
||||
type TCA2 = Cases<'BAR'>; // 'BAR bar BAR bAR'
|
||||
|
||||
// Assignability
|
||||
|
||||
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
|
||||
let s1: string = name;
|
||||
let s2: 'getFoo' | 'getBar' = name;
|
||||
}
|
||||
|
||||
function fa1<T>(x: T, y: { [P in keyof T]: T[P] }, z: { [P in keyof T & string as `p_${P}`]: T[P] }) {
|
||||
y = x;
|
||||
z = x; // Error
|
||||
}
|
||||
|
||||
function fa2<T, U extends T, A extends string, B extends A>(x: { [P in B as `p_${P}`]: T }, y: { [Q in A as `p_${Q}`]: U }) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
// String transformations using recursive conditional types
|
||||
|
||||
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
|
||||
T extends [] ? '' :
|
||||
T extends [unknown] ? `${T[0]}` :
|
||||
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
|
||||
string;
|
||||
|
||||
type TJ1 = Join<[1, 2, 3, 4], '.'>
|
||||
type TJ2 = Join<['foo', 'bar', 'baz'], '-'>;
|
||||
type TJ3 = Join<[], '.'>
|
||||
|
||||
// Inference based on delimiters
|
||||
|
||||
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
|
||||
|
||||
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
|
||||
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
|
||||
type T22 = MatchPair<' [1,2]'>; // unknown
|
||||
type T23 = MatchPair<'[123]'>; // unknown
|
||||
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
|
||||
|
||||
type SnakeToCamelCase<S extends string> =
|
||||
S extends `${infer T}_${infer U}` ? `${lowercase T}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${lowercase T}` :
|
||||
SnakeToPascalCase<S>;
|
||||
|
||||
type SnakeToPascalCase<S extends string> =
|
||||
string extends S ? string :
|
||||
S extends `${infer T}_${infer U}` ? `${capitalize `${lowercase T}`}${SnakeToPascalCase<U>}` :
|
||||
S extends `${infer T}` ? `${capitalize `${lowercase T}`}` :
|
||||
never;
|
||||
|
||||
type RR0 = SnakeToPascalCase<'hello_world_foo'>; // 'HelloWorldFoo'
|
||||
type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; // 'FooBarBaz'
|
||||
type RR2 = SnakeToCamelCase<'hello_world_foo'>; // 'helloWorldFoo'
|
||||
type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; // 'fooBarBaz'
|
||||
|
||||
// Single character inference
|
||||
|
||||
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
|
||||
|
||||
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
|
||||
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
|
||||
type T27 = FirstTwoAndRest<'a'>; // unknown
|
||||
|
||||
type Capitalize<S extends string> = S extends `${infer H}${infer T}` ? `${uppercase H}${T}` : S;
|
||||
type Uncapitalize<S extends string> = S extends `${infer H}${infer T}` ? `${lowercase H}${T}` : S;
|
||||
|
||||
type TC1 = Capitalize<'foo'>; // 'Foo'
|
||||
type TC2 = Uncapitalize<'Foo'>; // 'foo'
|
||||
|
||||
type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' |'8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
||||
|
||||
type HexColor<S extends string> =
|
||||
S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ?
|
||||
[R1, R2, G1, G2, B1, B2] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ?
|
||||
S :
|
||||
never :
|
||||
never;
|
||||
|
||||
type TH1 = HexColor<'#8080FF'>; // '#8080FF'
|
||||
type TH2 = HexColor<'#80c0ff'>; // '#80c0ff'
|
||||
type TH3 = HexColor<'#8080F'>; // never
|
||||
type TH4 = HexColor<'#8080FFF'>; // never
|
||||
|
||||
// Recursive inference
|
||||
|
||||
type Trim<S extends string> =
|
||||
S extends ` ${infer T}` ? Trim<T> :
|
||||
S extends `${infer T} ` ? Trim<T> :
|
||||
S;
|
||||
|
||||
type TR1 = Trim<'xx '>; // 'xx'
|
||||
type TR2 = Trim<' xx'>; // 'xx'
|
||||
type TR3 = Trim<' xx '>; // 'xx'
|
||||
|
||||
type Split<S extends string, D extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends '' ? [] :
|
||||
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
|
||||
[S];
|
||||
|
||||
type T40 = Split<'foo', '.'>; // ['foo']
|
||||
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
|
||||
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
|
||||
type T43 = Split<any, '.'>; // string[]
|
||||
|
||||
// Inference and property name paths
|
||||
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string, P2 extends keyof T[P0][P1] & string>(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2];
|
||||
declare function getProp<T, P0 extends keyof T & string, P1 extends keyof T[P0] & string>(obj: T, path: `${P0}.${P1}`): T[P0][P1];
|
||||
declare function getProp<T, P0 extends keyof T & string>(obj: T, path: P0): T[P0];
|
||||
declare function getProp(obj: object, path: string): unknown;
|
||||
|
||||
let p1 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a');
|
||||
let p2 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b');
|
||||
let p3 = getProp({ a: { b: {c: 42, d: 'hello' }}} as const, 'a.b.d');
|
||||
|
||||
type PropType<T, Path extends string> =
|
||||
string extends Path ? unknown :
|
||||
Path extends keyof T ? T[Path] :
|
||||
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
|
||||
unknown;
|
||||
|
||||
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
|
||||
declare const s: string;
|
||||
|
||||
const obj = { a: { b: {c: 42, d: 'hello' }}};
|
||||
|
||||
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
|
||||
getPropValue(obj, 'a.b'); // {c: number, d: string }
|
||||
getPropValue(obj, 'a.b.d'); // string
|
||||
getPropValue(obj, 'a.b.x'); // unknown
|
||||
getPropValue(obj, s); // unknown
|
||||
|
||||
// Infer type variables in template literals have string constraint
|
||||
|
||||
type S1<T> = T extends `foo${infer U}bar` ? S2<U> : never;
|
||||
type S2<S extends string> = S;
|
||||
|
||||
// Batched single character inferences for lower recursion depth
|
||||
|
||||
type Chars<S extends string> =
|
||||
string extends S ? string[] :
|
||||
S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars<R>] :
|
||||
S extends `${infer C}${infer R}` ? [C, ...Chars<R>] :
|
||||
S extends '' ? [] :
|
||||
never;
|
||||
|
||||
type L1 = Chars<'FooBarBazThisIsALongerString'>; // ['F', 'o', 'o', 'B', 'a', 'r', ...]
|
||||
|
||||
// Cross product unions limited to 100,000 constituents
|
||||
|
||||
type A = any;
|
||||
|
||||
type U1 = {a1:A} | {b1:A} | {c1:A} | {d1:A} | {e1:A} | {f1:A} | {g1:A} | {h1:A} | {i1:A} | {j1:A};
|
||||
type U2 = {a2:A} | {b2:A} | {c2:A} | {d2:A} | {e2:A} | {f2:A} | {g2:A} | {h2:A} | {i2:A} | {j2:A};
|
||||
type U3 = {a3:A} | {b3:A} | {c3:A} | {d3:A} | {e3:A} | {f3:A} | {g3:A} | {h3:A} | {i3:A} | {j3:A};
|
||||
type U4 = {a4:A} | {b4:A} | {c4:A} | {d4:A} | {e4:A} | {f4:A} | {g4:A} | {h4:A} | {i4:A} | {j4:A};
|
||||
type U5 = {a5:A} | {b5:A} | {c5:A} | {d5:A} | {e5:A} | {f5:A} | {g5:A} | {h5:A} | {i5:A} | {j5:A};
|
||||
|
||||
type U100000 = U1 & U2 & U3 & U4 & U5; // Error
|
||||
|
||||
type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
|
||||
type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; // Error
|
||||
|
||||
type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9];
|
||||
|
||||
type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; // Error
|
||||
32
tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts
Normal file
32
tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts
Normal file
@ -0,0 +1,32 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Mapped type 'as N' clauses
|
||||
|
||||
type Getters<T> = { [P in keyof T & string as `get${capitalize P}`]: () => T[P] };
|
||||
type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>;
|
||||
|
||||
// Mapped type with 'as N' clause has no constraint on 'in T' clause
|
||||
|
||||
type PropDef<K extends keyof any, T> = { name: K, type: T };
|
||||
|
||||
type TypeFromDefs<T extends PropDef<keyof any, any>> = { [P in T as P['name']]: P['type'] };
|
||||
|
||||
type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>;
|
||||
|
||||
// No array or tuple type mapping when 'as N' clause present
|
||||
|
||||
type TA1 = Getters<string[]>;
|
||||
type TA2 = Getters<[number, boolean]>;
|
||||
|
||||
// Filtering using 'as N' clause
|
||||
|
||||
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
|
||||
type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>;
|
||||
|
||||
// Mapping to multiple names using 'as N' clause
|
||||
|
||||
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
|
||||
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
|
||||
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
|
||||
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
|
||||
Loading…
x
Reference in New Issue
Block a user