microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.84k stars 12.36k forks source link

Expose MappedType in typescript.d.ts #59221

Open JoshuaKGoldberg opened 1 month ago

JoshuaKGoldberg commented 1 month ago

πŸ” Search Terms

mappedtype interface typeParameter constraintType templateType

βœ… Viability Checklist

⭐ Suggestion

Coming over from typescript-eslint, we need to look at the properties on mapped types for the @typescript-eslint/no-unnecessary-type-parameters ("Golden Rule of Generics") rule. But, MappedType is marked as @internal in TypeScript's definition:

https://github.com/microsoft/TypeScript/blob/22bbe867fd4b86e2187270f6c284e6cfd92a3fea/src/compiler/types.ts#L6584-L6594

Could we have that interface be public, please? Even if all the fields other than constraintType, templateType, and typeParameter are switched to @internal. I don't know of a more sanctioned way to access those type properties. Is there one?

πŸ“ƒ Motivating Example

Marking MappedType as public would provide a way for type checker API consumers to reason about mapped types.

πŸ’» Use Cases

See https://github.com/typescript-eslint/typescript-eslint/pull/8173 & https://github.com/typescript-eslint/typescript-eslint/pull/9530: in typescript-eslint, we need to access a few properties of mapped types to check if they're uses of a type parameter. We ended up writing our own interface MappedType extends ts.ObjectType:

interface MappedType extends ts.ObjectType {
  typeParameter?: ts.Type; // #8173
  constraintType?: ts.Type; // #9530
  templateType?: ts.Type; // #9530
}
weswigham commented 1 month ago

FYI, those properties are lazily created by functions within the checker - they're just cache fields, which is why they're optional, and we use functions within the checker to calculate, cache, and access them. Relying on their direct presence is risky.