Jsdoc property description (#50269)

* jsdocPropertyDescription

* jsdocPropertyDescription

* jsdocPropertyDescription

* Fixes #47933

* added additional test

* added additional example

* fixed bug

* changed function to only grab the literal type

* added additional condition for literals and symbols

* added additional test cases

* Update src/services/symbolDisplay.ts

Co-authored-by: Andrew Branch <andrewbranch@users.noreply.github.com>

* addressed PR review

* addressed new PR review

Co-authored-by: Danay Fernandez Alfonso <t-danayf@microsoft.com>
Co-authored-by: Andrew Branch <andrewbranch@users.noreply.github.com>
This commit is contained in:
Danay
2022-08-25 11:57:32 -07:00
committed by GitHub
co-authored by Andrew Branch Danay Fernandez Alfonso
parent 5ba22e05a9
commit a08b045d2b
38 changed files with 322 additions and 5 deletions
+30
View File
@@ -439,6 +439,7 @@ namespace ts {
getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)),
getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === IndexKind.String ? stringType : numberType),
getIndexInfosOfType,
getIndexInfosOfIndexSymbol,
getSignaturesOfType,
getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType),
getIndexType: type => getIndexType(type),
@@ -42615,6 +42616,35 @@ namespace ts {
if (name.kind === SyntaxKind.PropertyAccessExpression) {
checkPropertyAccessExpression(name, CheckMode.Normal);
if (!links.resolvedSymbol) {
const expressionType = checkExpressionCached(name.expression);
const infos = getApplicableIndexInfos(expressionType, getLiteralTypeFromPropertyName(name.name));
if (infos.length && (expressionType as ObjectType).members) {
const resolved = resolveStructuredTypeMembers(expressionType as ObjectType);
const symbol = resolved.members.get(InternalSymbolName.Index);
if (infos === getIndexInfosOfType(expressionType)) {
links.resolvedSymbol = symbol;
}
else if (symbol) {
const symbolLinks = getSymbolLinks(symbol);
const declarationList = mapDefined(infos, i => i.declaration);
const nodeListId = map(declarationList, getNodeId).join(",");
if (!symbolLinks.filteredIndexSymbolCache) {
symbolLinks.filteredIndexSymbolCache = new Map();
}
if (symbolLinks.filteredIndexSymbolCache.has(nodeListId)) {
links.resolvedSymbol = symbolLinks.filteredIndexSymbolCache.get(nodeListId)!;
}
else {
const copy = createSymbol(SymbolFlags.Signature, InternalSymbolName.Index);
copy.declarations = mapDefined(infos, i => i.declaration);
copy.parent = expressionType.aliasSymbol ? expressionType.aliasSymbol : expressionType.symbol ? expressionType.symbol : getSymbolAtLocation(copy.declarations[0].parent);
symbolLinks.filteredIndexSymbolCache.set(nodeListId, copy);
links.resolvedSymbol = symbolLinks.filteredIndexSymbolCache.get(nodeListId)!;
}
}
}
}
}
else {
checkQualifiedName(name, CheckMode.Normal);
+2
View File
@@ -4557,6 +4557,7 @@ namespace ts {
/* @internal */ getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined;
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
getIndexInfosOfType(type: Type): readonly IndexInfo[];
getIndexInfosOfIndexSymbol: (indexSymbol: Symbol) => IndexInfo[];
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;
/* @internal */ getIndexType(type: Type): Type;
@@ -5373,6 +5374,7 @@ namespace ts {
isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor
tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label
accessibleChainCache?: ESMap<string, Symbol[] | undefined>;
filteredIndexSymbolCache?: ESMap<string, Symbol> //Symbol with applicable declarations
}
/* @internal */
+31 -5
View File
@@ -64,6 +64,7 @@ namespace ts.SymbolDisplay {
if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement;
if (flags & SymbolFlags.Method) return ScriptElementKind.memberFunctionElement;
if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
if (flags & SymbolFlags.Signature) return ScriptElementKind.indexSignatureElement;
if (flags & SymbolFlags.Property) {
if (flags & SymbolFlags.Transient && (symbol as TransientSymbol).checkFlags & CheckFlags.Synthetic) {
@@ -506,7 +507,6 @@ namespace ts.SymbolDisplay {
else {
addPrefixForAnyFunctionOrVar(symbol, symbolKind);
}
// For properties, variables and local vars: show the type
if (symbolKind === ScriptElementKind.memberVariableElement ||
symbolKind === ScriptElementKind.memberGetAccessorElement ||
@@ -514,11 +514,12 @@ namespace ts.SymbolDisplay {
symbolKind === ScriptElementKind.jsxAttribute ||
symbolFlags & SymbolFlags.Variable ||
symbolKind === ScriptElementKind.localVariableElement ||
symbolKind === ScriptElementKind.indexSignatureElement ||
isThisExpression) {
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
displayParts.push(spacePart());
// If the type is type parameter, format it specially
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) {
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter && symbolKind !== ScriptElementKind.indexSignatureElement) {
const typeParameterParts = mapToDisplayParts(writer => {
const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!;
getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
@@ -639,13 +640,38 @@ namespace ts.SymbolDisplay {
}
function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) {
let indexInfos;
if (alias && symbolToDisplay === symbol) {
symbolToDisplay = alias;
}
const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind);
addRange(displayParts, fullSymbolDisplayParts);
if (symbolKind === ScriptElementKind.indexSignatureElement) {
indexInfos = typeChecker.getIndexInfosOfIndexSymbol(symbolToDisplay);
}
let fullSymbolDisplayParts: SymbolDisplayPart[] = [];
if (symbolToDisplay.flags & SymbolFlags.Signature && indexInfos) {
if (symbolToDisplay.parent) {
fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay.parent);
}
fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.OpenBracketToken));
//Needed to handle more than one type of index
indexInfos.forEach((info, i) => {
//Needed to handle template literals
fullSymbolDisplayParts.push(...typeToDisplayParts(typeChecker, info.keyType));
if (i !== indexInfos.length - 1) {
fullSymbolDisplayParts.push(spacePart());
fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.BarToken));
fullSymbolDisplayParts.push(spacePart());
}
});
fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.CloseBracketToken));
}
else {
fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind);
}
addRange(displayParts, fullSymbolDisplayParts);
if (symbol.flags & SymbolFlags.Optional) {
displayParts.push(punctuationPart(SyntaxKind.QuestionToken));
}
+1
View File
@@ -2316,6 +2316,7 @@ declare namespace ts {
getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined;
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
getIndexInfosOfType(type: Type): readonly IndexInfo[];
getIndexInfosOfIndexSymbol: (indexSymbol: Symbol) => IndexInfo[];
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;
getBaseTypes(type: InterfaceType): BaseType[];
+1
View File
@@ -2316,6 +2316,7 @@ declare namespace ts {
getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined;
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
getIndexInfosOfType(type: Type): readonly IndexInfo[];
getIndexInfosOfIndexSymbol: (indexSymbol: Symbol) => IndexInfo[];
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;
getBaseTypes(type: InterfaceType): BaseType[];
@@ -13,7 +13,9 @@ if (typeof config['works'] !== 'boolean') {
config.works.prop = 'test'; // ok
>config.works.prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
>config.works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
>config : Symbol(config, Decl(controlFlowElementAccess2.ts, 0, 13))
>works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
>prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
config['works'].prop = 'test'; // error, config['works']: boolean | { 'prop': string }
@@ -22,7 +24,9 @@ if (typeof config['works'] !== 'boolean') {
>prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
}
if (typeof config.works !== 'boolean') {
>config.works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
>config : Symbol(config, Decl(controlFlowElementAccess2.ts, 0, 13))
>works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
config['works'].prop = 'test'; // error, config['works']: boolean | { 'prop': string }
>config['works'].prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
@@ -31,7 +35,9 @@ if (typeof config.works !== 'boolean') {
config.works.prop = 'test'; // ok
>config.works.prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
>config.works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
>config : Symbol(config, Decl(controlFlowElementAccess2.ts, 0, 13))
>works : Symbol(__index, Decl(controlFlowElementAccess2.ts, 0, 23))
>prop : Symbol(prop, Decl(controlFlowElementAccess2.ts, 1, 30))
}
@@ -14,11 +14,15 @@ declare const value: A;
>A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0))
if (value.foo !== null) {
>value.foo : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
>foo : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
value.foo.toExponential()
>value.foo.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
>value.foo : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
>foo : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
value.other // should still be number | null
@@ -27,6 +31,8 @@ if (value.foo !== null) {
>other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10))
value.bar // should still be number | null
>value.bar : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
>bar : Symbol(A.__index, Decl(controlFlowStringIndex.ts, 1, 25))
}
@@ -105,10 +105,14 @@ delete f.j
>f : Symbol(f, Decl(deleteExpressionMustBeOptional.ts, 20, 13))
delete a.a
>a.a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional.ts, 21, 13))
>a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
delete a.b
>a.b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional.ts, 21, 13))
>b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
delete b.a
>b : Symbol(b, Decl(deleteExpressionMustBeOptional.ts, 22, 13))
@@ -105,10 +105,14 @@ delete f.j
>f : Symbol(f, Decl(deleteExpressionMustBeOptional.ts, 20, 13))
delete a.a
>a.a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional.ts, 21, 13))
>a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
delete a.b
>a.b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional.ts, 21, 13))
>b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional.ts, 12, 14))
delete b.a
>b : Symbol(b, Decl(deleteExpressionMustBeOptional.ts, 22, 13))
@@ -158,10 +158,14 @@ delete g.j
>g : Symbol(g, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 21, 13))
delete a.a
>a.a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
>a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
delete a.b
>a.b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
>b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
delete b.a
>b : Symbol(b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 23, 13))
@@ -158,10 +158,14 @@ delete g.j
>g : Symbol(g, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 21, 13))
delete a.a
>a.a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
>a : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
delete a.b
>a.b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
>b : Symbol(AA.__index, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 12, 14))
delete b.a
>b : Symbol(b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 23, 13))
@@ -8,7 +8,9 @@
(x) => ({ "1": "one", "2": "two" } as { [key: string]: string }).x;
>x : Symbol(x, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 1))
>({ "1": "one", "2": "two" } as { [key: string]: string }).x : Symbol(__index, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 39))
>"1" : Symbol("1", Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 9))
>"2" : Symbol("2", Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 21))
>key : Symbol(key, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 41))
>x : Symbol(__index, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES5.ts, 1, 39))
@@ -8,7 +8,9 @@
(x) => ({ "1": "one", "2": "two" } as { [key: string]: string }).x;
>x : Symbol(x, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 1))
>({ "1": "one", "2": "two" } as { [key: string]: string }).x : Symbol(__index, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 39))
>"1" : Symbol("1", Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 9))
>"2" : Symbol("2", Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 21))
>key : Symbol(key, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 41))
>x : Symbol(__index, Decl(emitAccessExpressionOfCastedObjectLiteralExpressionInArrowFunctionES6.ts, 1, 39))
@@ -133,7 +133,9 @@ const y1 = dom['data123'];
const y2 = dom.data123;
>y2 : Symbol(y2, Decl(indexSignatures1.ts, 47, 5))
>dom.data123 : Symbol(__index, Decl(indexSignatures1.ts, 45, 18))
>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11))
>data123 : Symbol(__index, Decl(indexSignatures1.ts, 45, 18))
// Excess property checking for template pattern index signature
@@ -90,7 +90,9 @@ function f2<T extends { [key: string]: number }>(a: { x: number, y: number }, b:
>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53))
b.x;
>b.x : Symbol(__index, Decl(keyofAndIndexedAccess2.ts, 12, 82))
>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77))
>x : Symbol(__index, Decl(keyofAndIndexedAccess2.ts, 12, 82))
c.x;
>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107))
@@ -105,7 +107,9 @@ function f2<T extends { [key: string]: number }>(a: { x: number, y: number }, b:
>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53))
b.x = 1;
>b.x : Symbol(__index, Decl(keyofAndIndexedAccess2.ts, 12, 82))
>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77))
>x : Symbol(__index, Decl(keyofAndIndexedAccess2.ts, 12, 82))
c.x = 1; // Error, cannot write to index signature through constraint
>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107))
@@ -51,7 +51,9 @@ a["foo"]
// access index signature
b.foo;
>b.foo : Symbol(B.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 4, 13))
>b : Symbol(b, Decl(noPropertyAccessFromIndexSignature1.ts, 14, 13))
>foo : Symbol(B.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 4, 13))
b["foo"];
>b : Symbol(b, Decl(noPropertyAccessFromIndexSignature1.ts, 14, 13))
@@ -68,7 +70,9 @@ c["foo"]
// access index signature
c.bar;
>c.bar : Symbol(C.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 9, 15))
>c : Symbol(c, Decl(noPropertyAccessFromIndexSignature1.ts, 15, 13))
>bar : Symbol(C.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 9, 15))
c["bar"];
>c : Symbol(c, Decl(noPropertyAccessFromIndexSignature1.ts, 15, 13))
@@ -85,7 +89,9 @@ d?.["foo"]
// optional access index signature
d?.bar;
>d?.bar : Symbol(C.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 9, 15))
>d : Symbol(d, Decl(noPropertyAccessFromIndexSignature1.ts, 16, 13))
>bar : Symbol(C.__index, Decl(noPropertyAccessFromIndexSignature1.ts, 9, 15))
d?.["bar"];
>d : Symbol(d, Decl(noPropertyAccessFromIndexSignature1.ts, 16, 13))
@@ -36,7 +36,9 @@ const e1: boolean = strMap["foo"];
const e2: boolean = strMap.bar;
>e2 : Symbol(e2, Decl(noUncheckedIndexedAccess.ts, 12, 5))
>strMap.bar : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
>strMap : Symbol(strMap, Decl(noUncheckedIndexedAccess.ts, 8, 13))
>bar : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
const e3: boolean = strMap[0];
>e3 : Symbol(e3, Decl(noUncheckedIndexedAccess.ts, 13, 5))
@@ -114,7 +116,9 @@ const ok1: boolean | undefined = strMap["foo"];
const ok2: boolean | undefined = strMap.bar;
>ok2 : Symbol(ok2, Decl(noUncheckedIndexedAccess.ts, 28, 5))
>strMap.bar : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
>strMap : Symbol(strMap, Decl(noUncheckedIndexedAccess.ts, 8, 13))
>bar : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
type T_OK1 = CheckBooleanOnly<(typeof strMap)[string]>;
>T_OK1 : Symbol(T_OK1, Decl(noUncheckedIndexedAccess.ts, 28, 44))
@@ -147,7 +151,9 @@ strMap["baz"] = undefined;
>undefined : Symbol(undefined)
strMap.qua = undefined;
>strMap.qua : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
>strMap : Symbol(strMap, Decl(noUncheckedIndexedAccess.ts, 8, 13))
>qua : Symbol(__index, Decl(noUncheckedIndexedAccess.ts, 8, 23))
>undefined : Symbol(undefined)
strMap[0] = undefined;
@@ -11,5 +11,7 @@ declare var a: Test;
>Test : Symbol(Test, Decl(propertyAccessOfReadonlyIndexSignature.ts, 0, 0))
a.foo = 'baz';
>a.foo : Symbol(Test.__index, Decl(propertyAccessOfReadonlyIndexSignature.ts, 0, 16))
>a : Symbol(a, Decl(propertyAccessOfReadonlyIndexSignature.ts, 4, 11))
>foo : Symbol(Test.__index, Decl(propertyAccessOfReadonlyIndexSignature.ts, 0, 16))
@@ -8,13 +8,19 @@ let flags: Flags;
>Flags : Symbol(Flags, Decl(propertyAccessStringIndexSignature.ts, 0, 0))
flags.b;
>flags.b : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignature.ts, 1, 3))
>b : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
flags.f;
>flags.f : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignature.ts, 1, 3))
>f : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
flags.isNotNecessarilyNeverFalse;
>flags.isNotNecessarilyNeverFalse : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignature.ts, 1, 3))
>isNotNecessarilyNeverFalse : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignature.ts, 0, 17))
flags['this is fine'];
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignature.ts, 1, 3))
@@ -8,13 +8,19 @@ let flags: Flags;
>Flags : Symbol(Flags, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 0))
flags.b;
>flags.b : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 1, 3))
>b : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
flags.f;
>flags.f : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 1, 3))
>f : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
flags.isNotNecessarilyNeverFalse;
>flags.isNotNecessarilyNeverFalse : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 1, 3))
>isNotNecessarilyNeverFalse : Symbol(Flags.__index, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 0, 17))
flags['this is fine'];
>flags : Symbol(flags, Decl(propertyAccessStringIndexSignatureNoImplicitAny.ts, 1, 3))
@@ -13,7 +13,9 @@ C["foo"] = 1
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
C.bar = 2;
>C.bar : Symbol(C.__index, Decl(staticIndexSignature1.ts, 0, 9))
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
>bar : Symbol(C.__index, Decl(staticIndexSignature1.ts, 0, 9))
const foo = C["foo"]
>foo : Symbol(foo, Decl(staticIndexSignature1.ts, 7, 5))
@@ -13,7 +13,9 @@ C["foo"] = 1
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
C.bar = 2;
>C.bar : Symbol(C.__index, Decl(staticIndexSignature2.ts, 0, 9))
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
>bar : Symbol(C.__index, Decl(staticIndexSignature2.ts, 0, 9))
const foo = C["foo"]
>foo : Symbol(foo, Decl(staticIndexSignature2.ts, 7, 5))
@@ -40,8 +40,12 @@ if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
B.a = D.a
>B.a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>D.a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
B[2] = D[2]
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
@@ -51,8 +55,12 @@ if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
D.a = B.a
>D.a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>B.a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
D[2] = B[2]
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
@@ -62,16 +70,24 @@ if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
B.a = i.a
>B.a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>i.a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
B[2] = i[2]
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
D.a = i.a
>D.a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>i.a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
D[2] = i [2]
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
@@ -81,8 +97,12 @@ if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
i.a = B.a
>i.a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>B.a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>a : Symbol(B.__index, Decl(staticIndexSignature4.ts, 0, 9))
i[2] = B[2]
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
@@ -92,8 +112,12 @@ if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
i.a = D.a
>i.a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>a : Symbol(IB.__index, Decl(staticIndexSignature4.ts, 10, 14))
>D.a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>a : Symbol(D.__index, Decl(staticIndexSignature4.ts, 5, 9))
i[2] = B[2]
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
@@ -24,10 +24,14 @@ const C = foo()
>foo : Symbol(foo, Decl(staticIndexSignature6.ts, 0, 0))
C.a;
>C.a : Symbol((Anonymous class).__index, Decl(staticIndexSignature6.ts, 1, 21))
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
>a : Symbol((Anonymous class).__index, Decl(staticIndexSignature6.ts, 1, 21))
C.a = 1;
>C.a : Symbol((Anonymous class).__index, Decl(staticIndexSignature6.ts, 1, 21))
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
>a : Symbol((Anonymous class).__index, Decl(staticIndexSignature6.ts, 1, 21))
C[2];
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
@@ -93,7 +93,9 @@ extend2({
>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1))
this.mine
>this.mine : Symbol(IndexedWithoutThis.__index, Decl(thisTypeInFunctions2.ts, 9, 29))
>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1))
>mine : Symbol(IndexedWithoutThis.__index, Decl(thisTypeInFunctions2.ts, 9, 29))
},
mine: 13,
@@ -106,7 +108,9 @@ extend2({
>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1))
this.mine
>this.mine : Symbol(IndexedWithoutThis.__index, Decl(thisTypeInFunctions2.ts, 9, 29))
>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1))
>mine : Symbol(IndexedWithoutThis.__index, Decl(thisTypeInFunctions2.ts, 9, 29))
}
});
@@ -306,16 +306,22 @@ function f(i: Indexed) {
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
return i.a;
>i.a : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
>a : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
}
else if ("b" in i) {
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
return i.b;
>i.b : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
>b : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
}
return "c" in i && i.c;
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
>i.c : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
>i : Symbol(i, Decl(typeGuardOfFromPropNameInUnionType.ts, 96, 11))
>c : Symbol(Indexed.__index, Decl(typeGuardOfFromPropNameInUnionType.ts, 92, 19))
}
@@ -0,0 +1,15 @@
///<reference path="fourslash.ts" />
//// interface StringExample {
//// /** Something generic */
//// [p: string]: any;
//// /** Something specific */
//// property: number;
//// }
//// function stringExample(e: StringExample) {
//// console.log(e./*property*/property);
//// console.log(e./*string*/anything);
//// }
verify.quickInfoAt("property", "(property) StringExample.property: number", 'Something specific');
verify.quickInfoAt("string", "(index) StringExample[string]: any", "Something generic");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// class MultipleClass {
//// /** Something generic */
//// [key: number | symbol | `data-${string}` | `data-${number}`]: string;
//// }
//// function multipleClass(e: typeof MultipleClass) {
//// console.log(e./*multipleClass*/anything);
//// }
verify.quickInfoAt("multipleClass", "any");
@@ -0,0 +1,13 @@
///<reference path="fourslash.ts" />
//// type AliasExample = {
//// /** Something generic */
//// [p: string]: string;
//// /** Something else */
//// [key: `any${string}`]: string;
//// }
//// function aliasExample(e: AliasExample) {
//// console.log(e./*alias*/anything);
//// }
verify.quickInfoAt("alias", "(index) AliasExample[string | `any${string}`]: string", "Something generic\nSomething else");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// type SymbolAlias = {
//// /** Something generic */
//// [p: symbol]: string;
//// }
//// function symbolAlias(e: SymbolAlias) {
//// console.log(e./*symbolAlias*/anything);
//// }
verify.quickInfoAt("symbolAlias", "any");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// interface SymbolExample {
//// /** Something generic */
//// [key: symbol]: string;
//// }
//// function symbolExample(e: SymbolExample) {
//// console.log(e./*symbol*/anything);
//// }
verify.quickInfoAt("symbol", "any")
@@ -0,0 +1,13 @@
///<reference path="fourslash.ts" />
//// interface LiteralExample {
//// /** Something generic */
//// [key: `data-${string}`]: string;
//// /** Something else */
//// [key: `prefix${number}`]: number;
//// }
//// function literalExample(e: LiteralExample) {
//// console.log(e./*literal*/anything);
//// }
verify.quickInfoAt("literal", "any");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// interface MultipleExample {
//// /** Something generic */
//// [key: string | number | symbol]: string;
//// }
//// function multipleExample(e: MultipleExample) {
//// console.log(e./*multiple*/anything);
//// }
verify.quickInfoAt("multiple", "(index) MultipleExample[string | number | symbol]: string", "Something generic");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// interface Multiple1Example {
//// /** Something generic */
//// [key: number | symbol | `data-${string}` | `data-${number}`]: string;
//// }
//// function multiple1Example(e: Multiple1Example) {
//// console.log(e./*multiple1*/anything);
//// }
verify.quickInfoAt("multiple1", "any");
@@ -0,0 +1,16 @@
// /<reference path="fourslash.ts" />
//// interface Literal1Example {
//// [key: `prefix${string}`]: number | string;
//// /** Something else */
//// [key: `prefix${number}`]: number;
//// }
//// function literal1Example(e: Literal1Example) {
//// console.log(e./*literal1*/prefixMember);
//// console.log(e./*literal2*/anything);
//// console.log(e./*literal3*/prefix0);
//// }
verify.quickInfoAt("literal1", "(index) Literal1Example[`prefix${string}`]: string | number");
verify.quickInfoAt("literal2", "any");
verify.quickInfoAt("literal3", "(index) Literal1Example[`prefix${string}` | `prefix${number}`]: number", "Something else");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// class StringClass {
//// /** Something generic */
//// static [p: string]: any;
//// }
//// function stringClass(e: typeof StringClass) {
//// console.log(e./*stringClass*/anything);
//// }
verify.quickInfoAt("stringClass", "(index) StringClass[string]: any", "Something generic");
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
//// class SymbolClass {
//// /** Something generic */
//// static [p: symbol]: any;
//// }
//// function symbolClass(e: typeof SymbolClass) {
//// console.log(e./*symbolClass*/anything);
//// }
verify.quickInfoAt("symbolClass", "any");
@@ -0,0 +1,17 @@
///<reference path="fourslash.ts" />
//// class LiteralClass {
//// /** Something generic */
//// static [key: `prefix${string}`]: any;
//// /** Something else */
//// static [key: `prefix${number}`]: number;
//// }
//// function literalClass(e: typeof LiteralClass) {
//// console.log(e./*literal1Class*/prefixMember);
//// console.log(e./*literal2Class*/anything);
//// console.log(e./*literal3Class*/prefix0);
//// }
verify.quickInfoAt("literal1Class", "(index) LiteralClass[`prefix${string}`]: any", "Something generic");
verify.quickInfoAt("literal2Class", "any");
verify.quickInfoAt("literal3Class", "(index) LiteralClass[`prefix${string}` | `prefix${number}`]: any", "Something generic\nSomething else")