tsdoc icon indicating copy to clipboard operation
tsdoc copied to clipboard

RFC: Specify that doc comments are allowed on simple union types

Open biw opened this issue 6 years ago • 12 comments

Hello,

I can't find any documentation on adding tsdocs to a typescript string literal type. I was wondering if the following is possible:

type InputType = 
/** the TSDoc doesn't work for num1, but I'd like it to */
| 'num1'
/** the TSDoc doesn't work for num2, but I'd also like it to */
| 'num2'

export const test = (...input: InputType[]) => {
    return input
}

// I'd like to get the TSDoc from 'num1' string literal to show up
// when inputting it into the `tac` function but it does not currently show
test('num1')

I'm not 100% tied to using string literal types, so if there is another way to do this with enums, etc., I'd love to learn 😄

If the above is not currently possible, I'd love to work to add it to tsdoc (with some guidance 😄).

Thanks!

biw avatar Jun 25 '19 17:06 biw

Does the compiler preserve these comments in the emitted .d.ts files? I recall sometimes comments in certain places get discarded.

TSDoc itself doesn't (yet) dictate very specifically where comments can appear. That is determined by the documentation tool that uses the TSDoc library. Which tool are you using?

octogonz avatar Jun 25 '19 21:06 octogonz

Hi there, I have the same thing. I am using String Literal types to define classnames and would love to populate with some more information.

So basically:

type TClassnames = 
	| 'bg-color-red-500'
    | 'bg-color-red-600'

I would love to populate the docs on the right side of the intellisense:

Screenshot 2020-02-12 at 07 31 36

This is how we can document with properties:

Screenshot 2020-02-12 at 10 10 59

Which would be amazing to have on string literals

christianalfoni avatar Feb 12 '20 06:02 christianalfoni

Any progress on this issue?

littlecold233 avatar Apr 16 '20 03:04 littlecold233

To answer my earlier question, the TypeScript compiler does preserve these comments in the .d.ts file:

export declare type InputType = 
/** the TSDoc doesn't work for num1, but I'd like it to */
'num1'
/** the TSDoc doesn't work for num2, but I'd also like it to */
 | 'num2';

So I think this feature seems pretty reasonable. 👍

But as mentioned previously, the TSDoc standard can specify that "yes this is an appropriate place to put a comment", but the TSDoc library only parses comments. It does not parse API signatures. That part is handled by your documentation tool such as API Extractor or TypeDoc.

So you'd need to open an issue to request this feature for the documentation tool.

octogonz avatar Apr 16 '20 04:04 octogonz

If this is specified as valid, what would documented types look like? Right now both api-extractor and typedoc just display the type. Do we need special casing for unions? Are doc comments allowed on union types within another type? Would this result in users expecting to be able to include comments almost anywhere within a type and have them be picked up?

type Messy = [ /** a */ 1, /** b */ 2 | /** c */ 3]

Gerrit0 avatar Apr 20 '20 01:04 Gerrit0

@Gerrit0 my thinking to restrict this feature to a very special pattern that is commonly used like an enum. We could give it a name like "union enum".

For example, these would be union enums:

/**
 * A standard system color.
 */
export type Color = 
  /**
   * The color `#ff0000`
   */
  'red' | // do we care whether "|" is before/after the comment? Not really
  /**
   * The color `#00ff00`
   */
  'green' 
  /**
   * The color `#0000ff`
   */
  | 'blue';

/**
 * A binary digit.
 */
export type Bit = /** zero */  0  |  /** one*/ 1;

But it's optional. For example, maybe a documentation tool only treats a type as an "union enum" if at least one of the members has a /** */ comment.

And it would NOT apply to any other generalized expressions, not even this sort of thing:

// NOT a union enum:
type Mammal = Cat | Dog | Horse;

For the most part, such a feature would be a feature request for your particular documentation tool. If TSDoc "supports" this feature, its role is merely to:

  • specify that it's "standard" to put doc comments on these subexpressions
  • provide a declaration reference notation for referring to them

octogonz avatar Apr 24 '20 04:04 octogonz

~~It looks like this feature was accepted, when looking at the Version 1.0 tracking. According to Gerrit0's comment, it should be available by the end of the year if I understood correctly!~~

Edit: I misunderstood - see the comment below.

TheMrZZ avatar Sep 15 '20 14:09 TheMrZZ

Note: TypeDoc != TSDoc. This hasn't been added to the TSDoc standard yet, but TypeDoc plans to support it. Other documentation generators might not necessarily support it.

Gerrit0 avatar Sep 15 '20 15:09 Gerrit0

Note: TypeDoc != TSDoc. This hasn't been added to the TSDoc standard yet, but TypeDoc plans to support it. Other documentation generators might not necessarily support it.

Therefore, it was the 2nd case - me misunderstanding this basic thing. Sorry for the mistake, and thanks for the clarification!

As it is related, I'll rewrite below the comment I made on the official TypeScript repo.

This is an underrated feature. Nowadays, a lot of enum are done using string literals - a powerful feature that puts Typescript above a lot of static languages. However, those enumerations lack proper documentation, which causes several problems.

Here are a few real-world use-cases:

React Native CSS

<Text style={{
  color: 'blue',
  alignSelf: 'center',
}}> This is a blue text </Text>

Adding string comments would simplify the understanding of each possibility (each color, each possible alignments).

This is applicable to all properties with a defined set of string values.

Configuration files

For example, let's take a tsconfig.json file:

{
  "module": "commonjs"
}

Currently, the documentation looks like this: Capture d’écran de 2020-09-16 13-19-44

While we know all the possible options, there is no way to understand what they actually do. String comments could tell explicitly the user what each option is supposed to change.

This is applicable to all configuration files that are made with TS, not only tsconfig.json.

Material-UI

Material-UI relies a lot on string enumerations, but they are not always easy to understand.

<Button variant="contained"> My Button </Button>

In the above example, while variant is trivial to understand, it's not easy to guess what the "contained" value means. You have to rely on the external documentation, where that shouldn't be necessary.

This is applicable to all React props with a defined set of string values.

In conclusion, I think it's a very good idea, and it could simplify documentation in a lot of projects.

TheMrZZ avatar Sep 19 '20 14:09 TheMrZZ

Any progress on this issue today, plz

pangxiaoli avatar Aug 09 '22 03:08 pangxiaoli

Is this feature difficult to implement?

55Cancri avatar Oct 23 '22 15:10 55Cancri

FWIW, this doesn't appear to work for complex union/intersection types either until you've defined enough properties to resolve the full type, e.g.

export type Config = {
  /**
  * Testing
  */
  name: string;
  abstract?: boolean;
} & (
  | {
      storage?: Storage.Stream;
    }
  | {
      storage?: Storage.Dynamo;
      table?: string;
    }
);

const config1: Config = {
  name: "test" // no comment in tooltip
}

const config2: Config = {
  name: "test", // comment appears in tooltip
  storage: Storage.Stream
}

jonnyasmar avatar Feb 10 '23 08:02 jonnyasmar