TSServer plugin & Utilities for "expanding" TypeScript types

Overview

ts-expand-type

test1 copy

This repo provides a TS Server plugin which amends quick info to include the fully "expanded" type. "Expanded" means that object intersections are recursively merged, and nested type aliases are resolved.

Additionally, it exposes utilities for expanding types generated by the TypeScript Compiler. For more details, see Usage as a Library

Installing

To install locally, first install the package as a dev dependency (npm i -D ts-expand-type), and then add the following to your tsconfig.json:

{
    "compilerOptions": {
        // ...
        "plugins": [
            {
                "name": "ts-expand-type",
                // ...config options
            }
        ]
        // ...
    }
}

Some IDEs may support global plugins, since this feature is supported by tsserver. Consult your IDE's documentation for more info.

Note that if you are using VSCode, an extension is planned to integrate this feature standalone. Check back later for more info.

Config

Configuration options are set in the plugins options - see above. Available configuration options:

  • multilineObjectLiterals: Whether to force all object literals to be rendered across multiple lines. Defaults to true
  • includeOriginal: Whether to include the original quick info or override it with type info. Defaults to false
  • typePrefix: Whether to prefix the type info with the text (type). Defaults to true if includeOriginal is set, and false otherwise.

Planned Features

Planned features:

  • Support for mapped types
  • Union merging (#1)
  • Support for function types

Usage as a Library

This package exposes some API enpoints for acessing certain behavior. Specifically, you can import from ts-expand-type/dist/merge and ts-expand-type/dist/util.

The function you are probably most interested in is recursiveMergeIntersection from merge.js, which takes a type and "expands" it in the way described above. This should then be good to print using typeChecker.typeToString().

Testing

Write test cases in tests/cases. Running,

yarn test

Will generate "baselines," which test every typed node in the file, for each test case. It will then compare generated baselines to those in tests/baselines/reference. Any which fail will go into the tests/baselines/local folder, where you can inspect/diff them. To accept new baselines, run,

yarn baseline-accept

If you make a PR adding new features, please write at least one test case for that feature.

Building

First install deps with yarn install. To build,

yarn build
Comments
  • Improved mapped type tests

    Improved mapped type tests

    Fixes #24

    As mentioned in #23 some types will not resolve and this still happens with this tests, as of now im not aware on how i could write the test properly to fail when the type is not resolved, i tried to go on the .tree but felt that i would break the entire test if trying to change it by hand.

    I also included the test mentioned in #25 so when custom depth is added this can be tested easily

    opened by Didas-git 3
  • Test Errors

    Test Errors

    As of now running tests on the lib will always result in 2 errors. This errors come from the module.ts file and are a result of how the tests are writen, i dont think this is a huge issue but at least one that should be mentioned on the contributing.md file.

    Error: Screenshot 2022-11-14 at 10 31 32

    bug tests 
    opened by Didas-git 1
  • Allow configurable recursion depth

    Allow configurable recursion depth

    Currently, the internal recursion depth is capped at 6, which makes cases like this one cause max recursion nodes.

    This depth number should be user-configurable.

    Thanks to @Didas-git for the example and suggestion!

    enhancement vscode api 
    opened by mxsdev 1
  • Test that ensures we don't import non-types from typescript

    Test that ensures we don't import non-types from typescript

    Sometimes the bundle fails in vscode because an extraneous dependency (typescript) is require'd, but is not included in the bundle.

    This can probably be accomplished with this eslint rule, but the vscode integration tests should 100% be using the bundled version rather than --extensionDevPath.

    vscode tests 
    opened by mxsdev 1
  • Improve Promise types

    Improve Promise types

    Currently one of the major problems is that Promises are shown as an object type and do not give you the return type upfront. My idea would be to use the <type arguments> to defined the promise type since it contains the proper type of the promise. image

    Another issue is that promises show a rather useless tag when looking into them image

    opened by Didas-git 1
  • Type tree gets generated on every quick info call

    Type tree gets generated on every quick info call

    The TypeInfo tree will be generated on every call to getQuickInfo on the typescript server. This can potentially cause enormous slowdowns on hovers in VSCode.

    Ideally, the tsserver plugin would generate a type tree only upon a quick info call originating from the extension.

    performance tsserver 
    opened by mxsdev 1
  • Max recursion depth tooltip

    Max recursion depth tooltip

    Max recursion depth tree items should say "Max recursion exceeded" or something like that on hover, instead of just ellipses.

    This will help users understand that this is not occurring due to an error.

    enhancement vscode 
    opened by mxsdev 0
  • Complex mapped types can break symbol resolution

    Complex mapped types can break symbol resolution

    Example:

    interface FieldVals {
        string: string;
        number: number
    }
    
    type FieldFormat = Record<string, keyof FieldVals>
    
    type MapField<T extends FieldFormat> = {
        [K in keyof T]: FieldVals[T[K]]
    }
    
    declare function createField<T extends FieldFormat>(data: T): MapField<T>
    
    const f = createField({a: "string"})
    
    f.a
    

    f.a in the extension will resolve to the symbol a which is of type "string", rather than following the resolution through to FieldVals, which should result in type string.

    Thanks to @Didas-git for reporting this/providing the example!

    bug api 
    opened by mxsdev 0
  • Hide internal symbols

    Hide internal symbols

    Some types have show internal symbols such as the following:

    image

    Ideally, these should be hidden by default.

    From #18 (thanks to @Didas-git for the suggestion!)

    enhancement api 
    opened by mxsdev 0
  • Show type arguments in description

    Show type arguments in description

    Would be nice to show type arguments in descriptions. So, for example, the following:

    image

    Would display Promise<void> instead of Promise.

    There should probably be a config option to toggle this feature, as well as a maximum length before going to ellipsis (e.g. Promise<...>.

    From #18 (thanks to @Didas-git for the suggestion!)

    enhancement vscode api 
    opened by mxsdev 0
  • Not getting jsdoc from declarations

    Not getting jsdoc from declarations

    For symbols defined with declare, the declaration is not included as a location, which prevents us from retrieving the jsdoc. For example, in the following, Button (which is defined with declare) will have no jsdoc.

    import React from "react"
    import { Button } from "@mui/material"
    
    export const Component: React.FunctionComponent = () => (
        <Button>Button</Button>
    )
    
    bug api 
    opened by mxsdev 0
  • Type parameters sometimes not resolved

    Type parameters sometimes not resolved

    In many circumstances, type parameters are not resolved, even if type arguments are. For example:

    declare function name(): Promise<void>;
    

    The return type here will show void as a type argument, but will not display T, the relevant type parameter.

    Thanks to @Didas-git for pointing this out!

    bug api 
    opened by mxsdev 0
  • Incompatible with Svelte Plugin

    Incompatible with Svelte Plugin

    Since the plugin now overrides completions, plugins which interface with completions, such as the svelte plugin, are incompatible, and can cause errors retrieving info.

    There's probably a few ways to approach solving this, like returning dummy info, or forcing extension load order somehow (by e.g. requiring the svelte extension as a dependency, if VSCode provides a way to do that).

    bug api low priority 
    opened by mxsdev 0
  • Filtering/Sorting

    Filtering/Sorting

    Might be nice to allow more complex filtering/sorting options.

    For example, sort by type kind, sort alphabetically, filter non-methods, etc.

    One challenge with doing this is finding a way to make it feel natural using the menu options provided by the Extension API. Not sure if there's actually a way to have, for example, a checkmark on a menu option.

    enhancement vscode low priority 
    opened by mxsdev 1
  • Union Types

    Union Types

    Currently, union types are kept as union types, with their constituent parts recursively merged. This is pretty much the best you could hope to do, although there are a few things you can do:

    • Distribute intersections over unions
    • Extract the "greatest common denominator" from the union

    The first example means, for example, {a: any} & ({b: any} | {c: any}) -> {a: any, b: any} | {a: any, c: any}. The second is the exact reverse of this.

    The most useful is probably the second, i.e., extracting the common factors out of the union, since this leaves the union members as small as possible.

    The problem of finding a gcd out of some objects, however, is kind of non-trivial, because there is some serious requisite recursive logic. For example:

    type t = 
      |{
        a: any,
        b: {
            x: any,
            y: any,
        }
      }
      |{
        c: any,
        b: {
            y: any,
            z: any
        }
      }
    

    would need to be converted to:

    type t =
      {
        b: {
          y: any
        }
      } & (
        |{
          a: any,
          b: {
            x: any
          }
        }
        |{
          c: any,
          b: {
            z: any
          }
        }
      )
    

    The recursive logic is manageable, however the problem really here is type comparison. For example, in the above example, we have to determine that b.y is equal in every element of the union. And I'm not sure whether it's possible to compare types like this using only externally exported methods from the typeChecker.

    enhancement help wanted api 
    opened by mxsdev 0
Releases(v0.4.0)
Owner
Max Stoumen
Max Stoumen
Opinionated collection of TypeScript definitions and utilities for Deno and Deno Deploy. With complete types for Deno/NPM/TS config files, constructed from official JSON schemas.

Schemas Note: You can also import any type from the default module, ./mod.ts deno.json import { type DenoJson } from "https://deno.land/x/[email protected]

deno911 2 Oct 12, 2022
Compile-time tests for types. Useful to make sure types don't regress into being overly-permissive as changes go in over time.

expect-type Compile-time tests for types. Useful to make sure types don't regress into being overly-permissive as changes go in over time. Similar to

Misha Kaletsky 82 Jan 8, 2023
Basic types & utilities for Strapi v4 and plugin creators

Strapi v4 - Types & utilities Basic set of types and utilities for Strapi v4 and plugins creators A developers goodie for Strapi Headless CMS which pr

 VirtusLab Open-Source 7 Oct 14, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A web component for progressively-enhanced auto-expanding textareas

Elastic Textarea A web component for progressively-enhanced auto-expanding textareas. This web component progressively enhances the native textarea: a

Cloud Four 29 Jan 9, 2023
A lightweight vanilla JavaScript app for expanding and collapsing blocks of text.

Read more button A lightweight vanilla javascript read more button for expanding and collapsing blocks of text. Features Choose how many text to keep

tyah 2 May 11, 2022
Variant types in Roblox TypeScript - Ported from Vanilla TypeScript

Variant (for Roblox) This is a roblox typescript variant (heh, pun) of Variant. See the Variant documentation on how to use Variant. A variant type is

Australis 2 Jun 3, 2022
Simple "everyday CRUD" Postgres queries with perfect TypeScript types

Crudely Typed Simple "everyday CRUD" Postgres queries with perfect TypeScript types. Zero dependencies. Designed to work with pg-to-ts and node-postgr

Dan Vanderkam 26 Dec 26, 2022
🧩 TypeScript utility type in order to ensure to return only properties (not methods) containing values in primitive types such as number or boolean (not Value Objects)

?? TypeScript Primitives type TypeScript utility type in order to ensure to return only properties (not methods) containing values in primitive types

CodelyTV 82 Dec 7, 2022
🔒 The new way to do types in typescript.

Nominal The right way to do types in typescript. Installation npm install nominal-types yarn install nominal-types pnpm install nominal-types Usage

Modfy 251 Dec 24, 2022
A little utility type package that allows you to access the current TypeScript version from your types.

@phryneas/ts-version A little utility type package that allows you to access the current TypeScript version from your types. import { TSVersion } from

Lenz Weber-Tronic 11 Sep 4, 2022
🎊 A Collection of TypeScript types for the Kirby CMS

kirby-fest A collection of TypeScript types to work with Kirby, mainly in the context of the Kirby Query Language. Setup # pnpm pnpm add -D kirby-fest

Johann Schopplich 5 Nov 22, 2022
You can easily create the horizontal timeline with two types by using this jQuery plugin.

jQuery.Timeline V2 You are able to easily create two types of horizontal timeline with this jQuery plugin. Report bug · Request feature · Blog Table o

ka2 222 Dec 9, 2022
VSCode Extension & utilities for exploring TypeScript type information

ts-type-explorer VSCode Extension & utilities to explore type information in TypeScript projects. Installation Check out the releases page to download

Max Stoumen 6 Nov 20, 2022
Different Types of Monsters Card of Popular anime. Build in React tech.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: ya

Abhishek Tiwari 5 Mar 19, 2022
String Types For io-ts

io-ts-strings String types for io-ts npm install io-ts-strings Currently implemented types: Alpha AlphaNumeric Ascii Base32, Base58, Base64 BIC(SWIFT

Jesse Kelly 5 Mar 13, 2022
well yes, but can you do it in types?

Yes, but can you do it in types? A collection of challenges which you complete in solely the type system. Everyone knows you can write code to do thin

catgirlkelly 11 Oct 27, 2022