Open jayarjo opened 4 years ago
Could you share a more complete example that includes the definition of y
and isConfig
?
FYI this came up recently in a discussion https://github.com/microsoft/rushstack/issues/1874#issuecomment-633883380 for the API Extractor project, where someone was using the purify library to model JSON objects. (Probably it's related to your case here.)
There does not seem to be a straightforward way to generalize JSDoc-style doc comments to handle those types. My initial opinion was that complex inferred types are perhaps not the best way to represent an API contract that we want to document. 🙂 I have a personal bias, though. My bandwagon is to build software systems that are easy for strangers and beginners to learn and contribute to. Thus I would happily sacrifice conciseness and mathematical elegance in favor of coding patterns that are simple and avoid TypeScript's growing list of higher order operators and inferences. I don't mean to discourage complex types really, merely to say I have not explored this much myself.
There is a clear trend of developers who want to make these elaborate and heavily abstracted type declarations. It includes the TypeScript compiler owners, so this actually characterizes the TypeScript language to some extent. It would be great for TSDoc to support it.
If people have ideas, here's a good place to share them.
@rbuckton FYI
It's more about not having to update types in several places rather than elegance. Here's the slice of type that is generated and exported to corresponding d.ts
file:
declare const isConfig: y.ObjectSchema<{
image: string;
name: string;
env: object;
buildArgs: object;
exposedPorts: any;
networkMode: string;
bindMount: any;
startupTimeout: number;
cmd: string;
healthCheck: any;
auth: any;
useDefaultLogDriver: boolean;
}>;
Let us suppose that you wrote TSDoc comments like this:
declare const isConfig: y.ObjectSchema<{
/**
* the URL of the image
*/
image: string;
/**
* the name of the thing
*/
name: string;
/**
* additional environment variables to be passed along
* @remarks
* These should be mapping of string keys to string values.
* @defaultValue `undefined`
*/
env: object;
. . .
Now, the documentation tool would need to somehow analyze the compiler's inferred type for y.InferType<typeof isConfig>
and trace it back to those original declarations.
And the analysis would need to understand that string
in the expression image: string;
is not TypeScript's string. Confusingly this string
is an imported JavaScript object with the same name (that causes the inferred type to become a TypeScript string
).
But in the end, the doc comments here could be mapped to the inferred property signatures that they produce. And then pretty much the normal TSDoc rules would apply.
In fact, the TypeScript compiler could do most of the work for us, by emitting the inferred type in the .d.ts file, with the doc comments preserved in place.
Thinking about it that way, this discussion is not really about "complex" types. Rather the problem here is:
Where do you write comments for an inferred type, since it has no explicit source code?
And maybe the answer could be: On whatever thing that it was inferred from. And it's up to the compiler or documentation tool to figure out how to find that thing.
I mean the same way we have @param
, which overrides inferred definition, if present, we could have @property
. Then we could write comments anywhere.
@jayarjo Are you proposing something like this?
/**
* @property image - the URL of the image
* @property name - the name of the thing
* @property env - additional environment variables to be passed along
*/
export type Config = y.InferType<typeof isConfig>
This does not seem like it would work very well:
For a person reading this code, they would need to flip back and forth between type Config
and const isConfig
to figure out the types/signatures for each property. Maybe they are even in different source files.
How do we structure sections like @remarks
and @defaultValue
, which may be different for each property? This problem does not apply to @param
because function parameters generally need only minimal documentation, because the details are provided with the function itself.
@octogonz
@param
?
I have a complex type that is inferred from
yup
schema, so something like:How would one
ts-doc
its properties manually?