-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Way to expand complex type aliases (Awaited, ReturnType, typeof etc.) #2654
Comments
You're after |
Indeed, I missed Unfortunately, it behaves somewhat unexpectedly in the case when a function returns an array. For example: function doSth() {
return [{ abc: 123 }];
}
/** @interface */
export type DoSth = ReturnType<typeof doSth>; Expected:type DoSth = {
abc: number;
}[] Actual:interface DoSth {
[unscopables]: {
[unscopables]?: boolean;
length?: boolean;
[iterator]?: any;
at?: any;
concat?: any;
copyWithin?: any;
entries?: any;
every?: any;
fill?: any;
filter?: any;
find?: any;
findIndex?: any;
findLast?: any;
findLastIndex?: any;
flat?: any;
flatMap?: any;
forEach?: any;
includes?: any;
indexOf?: any;
join?: any;
keys?: any;
lastIndexOf?: any;
map?: any;
pop?: any;
push?: any;
reduce?: any;
reduceRight?: any;
reverse?: any;
shift?: any;
slice?: any;
some?: any;
sort?: any;
splice?: any;
toLocaleString?: any;
toReversed?: any;
toSorted?: any;
toSpliced?: any;
toString?: any;
unshift?: any;
values?: any;
with?: any;
};
length: number;
[iterator](): IterableIterator<{
abc: number;
}>;
at(index: number): undefined | {
abc: number;
};
concat(...items: ConcatArray<{
abc: number;
}>[]): {
abc: number;
}[];
concat(...items: ({
abc: number;
} | ConcatArray<{
abc: number;
}>)[]): {
abc: number;
}[];
copyWithin(target: number, start: number, end?: number): this;
entries(): IterableIterator<[number, {
abc: number;
}]>;
every<S>(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => value is S), thisArg?: any): this is S[];
every(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => unknown), thisArg?: any): boolean;
fill(value: {
abc: number;
}, start?: number, end?: number): this;
filter<S>(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => value is S), thisArg?: any): S[];
filter(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => unknown), thisArg?: any): {
abc: number;
}[];
filter(predicate: BooleanConstructor, thisArg?: unknown): {
abc: number;
}[];
find<S>(predicate: ((value: {
abc: number;
}, index: number, obj: {
abc: number;
}[]) => value is S), thisArg?: any): undefined | S;
find(predicate: ((value: {
abc: number;
}, index: number, obj: {
abc: number;
}[]) => unknown), thisArg?: any): undefined | {
abc: number;
};
findIndex(predicate: ((value: {
abc: number;
}, index: number, obj: {
abc: number;
}[]) => unknown), thisArg?: any): number;
findLast<S>(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => value is S), thisArg?: any): undefined | S;
findLast(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => unknown), thisArg?: any): undefined | {
abc: number;
};
findLastIndex(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => unknown), thisArg?: any): number;
flat<A, D>(this: A, depth?: D): FlatArray<A, D>[];
flatMap<U, This>(callback: ((this: This, value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => U | readonly U[]), thisArg?: This): U[];
forEach(callbackfn: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => void), thisArg?: any): void;
includes(searchElement: {
abc: number;
}, fromIndex?: number): boolean;
includes(searchElement: unknown, fromIndex?: number): searchElement is {
abc: number;
};
indexOf(searchElement: {
abc: number;
}, fromIndex?: number): number;
join(separator?: string): string;
keys(): IterableIterator<number>;
lastIndexOf(searchElement: {
abc: number;
}, fromIndex?: number): number;
map<U>(callbackfn: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => U), thisArg?: any): U[];
pop(): undefined | {
abc: number;
};
push(...items: {
abc: number;
}[]): number;
reduce(callbackfn: ((previousValue: {
abc: number;
}, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => {
abc: number;
})): {
abc: number;
};
reduce(callbackfn: ((previousValue: {
abc: number;
}, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => {
abc: number;
}), initialValue: {
abc: number;
}): {
abc: number;
};
reduce<U>(callbackfn: ((previousValue: U, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => U), initialValue: U): U;
reduceRight(callbackfn: ((previousValue: {
abc: number;
}, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => {
abc: number;
})): {
abc: number;
};
reduceRight(callbackfn: ((previousValue: {
abc: number;
}, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => {
abc: number;
}), initialValue: {
abc: number;
}): {
abc: number;
};
reduceRight<U>(callbackfn: ((previousValue: U, currentValue: {
abc: number;
}, currentIndex: number, array: {
abc: number;
}[]) => U), initialValue: U): U;
reverse(): {
abc: number;
}[];
shift(): undefined | {
abc: number;
};
slice(start?: number, end?: number): {
abc: number;
}[];
some(predicate: ((value: {
abc: number;
}, index: number, array: {
abc: number;
}[]) => unknown), thisArg?: any): boolean;
sort(compareFn?: ((a: {
abc: number;
}, b: {
abc: number;
}) => number)): this;
splice(start: number, deleteCount?: number): {
abc: number;
}[];
splice(start: number, deleteCount: number, ...items: {
abc: number;
}[]): {
abc: number;
}[];
toLocaleString(): string;
toLocaleString(locales: string | string[], options?: NumberFormatOptions & DateTimeFormatOptions): string;
toReversed(): {
abc: number;
}[];
toSorted(compareFn?: ((a: {
abc: number;
}, b: {
abc: number;
}) => number)): {
abc: number;
}[];
toSpliced(start: number, deleteCount: number, ...items: {
abc: number;
}[]): {
abc: number;
}[];
toSpliced(start: number, deleteCount?: number): {
abc: number;
}[];
toString(): string;
unshift(...items: {
abc: number;
}[]): number;
values(): IterableIterator<{
abc: number;
}>;
with(index: number, value: {
abc: number;
}): {
abc: number;
}[];
} |
That's working as expected -- it is accurately describing an TypeDoc doesn't have a tag to document a type alias using the "hovered type"... perhaps it should. I've avoided it so far as it is usually an indication that the code being documented would likely be improved by some other simplification. I do keep circling back to this every few months though, so should probably just include it at some point... It is easy to write a plugin which implements this functionality for now: // CC0
// typedoc --plugin ./path/to/plugin.js
// @ts-check
import td, { ReflectionKind } from "typedoc";
const TAG = "@useHoverType";
/** @param {td.Application} app */
export function load(app) {
// Automatically add the tag to the supported list of modifier tags
app.on(td.Application.EVENT_BOOTSTRAP_END, () => {
const tags = [...app.options.getValue("modifierTags")];
if (!tags.includes(TAG)) {
tags.push(TAG);
}
app.options.setValue("modifierTags", tags);
});
app.converter.on(td.Converter.EVENT_CREATE_DECLARATION, (context, decl) => {
const symbol = context.project.getSymbolFromReflection(decl);
if (!decl.kindOf(ReflectionKind.TypeAlias) || !decl.comment?.hasModifier(TAG) || !symbol) {
return;
}
decl.comment.removeModifier(TAG);
const type = context.checker.getDeclaredTypeOfSymbol(symbol);
decl.type = context.converter.convertType(context.withScope(decl), type);
});
} |
Is there a better semantic name for this than "hover type?" Or, if not a name - is there a good description of the semantics used for determining how hover tooltips are expanded? I'd be hesitant to use this for fear of it not being stable. |
Oh, it's definitely not stable. It's entirely dependent on whatever TypeScript decides to do - and that can and has changed between TS versions. |
Search Terms
Awaited, ReturnType, typeof
Problem
I often have types that rely on the implementation, i.e.:
Currently, the documentation generated for such type is:
It's not instantly useful to the users.
Suggested Solution
Expand the type to the extent that the TypeScript language server does by default. In this case, it shows an object – all aliases are squashed.
The text was updated successfully, but these errors were encountered: