Mapped types like Pick<T, K> should adopt property documentation from T.

Fixes #26430.
This commit is contained in:
Matt McCutchen 2018-08-13 19:56:20 -04:00
parent e8b72aa7d9
commit d7b802577c
2 changed files with 14 additions and 8 deletions

View file

@ -6666,7 +6666,7 @@ namespace ts {
if (isMappedTypeWithKeyofConstraintDeclaration(type)) { if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
// We have a { [P in keyof T]: X } // We have a { [P in keyof T]: X }
for (const prop of getPropertiesOfType(modifiersType)) { for (const prop of getPropertiesOfType(modifiersType)) {
addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), /*_index*/ undefined, prop); addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include));
} }
if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) {
addMemberForKeyType(stringType); addMemberForKeyType(stringType);
@ -6685,7 +6685,7 @@ namespace ts {
} }
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
function addMemberForKeyType(t: Type, _index?: number, origin?: Symbol) { function addMemberForKeyType(t: Type) {
// Create a mapper from T to the current iteration type constituent. Then, if the // 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 // mapped type is itself an instantiated type, combine the iteration mapper with the
// instantiation mapper. // instantiation mapper.
@ -6707,9 +6707,9 @@ namespace ts {
prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) :
strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
propType; propType;
if (origin) { if (modifiersProp) {
prop.syntheticOrigin = origin; prop.syntheticOrigin = modifiersProp;
prop.declarations = origin.declarations; prop.declarations = modifiersProp.declarations;
} }
prop.nameType = t; prop.nameType = t;
members.set(propName, prop); members.set(propName, prop);

View file

@ -1,11 +1,17 @@
/// <reference path="./fourslash.ts"/> /// <reference path="./fourslash.ts"/>
////interface I { m(): void; } ////interface I {
//// /** m documentation */ m(): void;
////}
////declare const o: { [K in keyof I]: number }; ////declare const o: { [K in keyof I]: number };
////o.m/*0*/; ////o.m/*0*/;
//// ////
////declare const p: { [K in keyof I]: I[K] }; ////declare const p: { [K in keyof I]: I[K] };
////p.m/*1*/; ////p.m/*1*/;
////
////declare const q: Pick<I, "m">;
////q.m/*2*/;
verify.quickInfoAt("0", "(property) m: number"); verify.quickInfoAt("0", "(property) m: number", "m documentation");
verify.quickInfoAt("1", "(method) m(): void"); verify.quickInfoAt("1", "(method) m(): void", "m documentation");
verify.quickInfoAt("2", "(method) m(): void", "m documentation");