Search code examples
typescripttypesrelative-pathdenoabsolute-path

How to set types for absolute path and relative path?


I need to deal with absolute path variables and relative path variables in Deno TypeScript. The std library has the ParsedPath type, but that's not specific enough. Besides adding the absolute/relative word in the variable name, is there a way to type it as well? At best it should work in both Windows and Linux, but if it's hard then Windows is suffice.


Solution

  • First, some observations:

    • The properties of the ParsedPath interface are mutable, so whatever type you derive from it must enforce that instances cannot be mutated (e.g. by using the utility Readonly<Type>) — otherwise, a consumer might make changes to it, which would circumvent the type system discrimination that you seek.

    • The string property root will be the empty string "" for relative parsed paths — which can be used to discriminate whether the path is relative or absolute.

    Here is an example:

    Code in TS Playground

    import { parse } from "https://deno.land/[email protected]/path/parse.ts";
    import type { ParsedPath } from "https://deno.land/[email protected]/path/_interface.ts";
    
    type AbsoluteParsedPath = Readonly<ParsedPath> & { readonly isAbsolute: true };
    type RelativeParsedPath = Readonly<ParsedPath> & { readonly isAbsolute: false };
    
    function parsePath(path: string): AbsoluteParsedPath | RelativeParsedPath {
      const parsed = parse(path);
      return Object.assign(parsed, { isAbsolute: parsed.root.length > 0 });
    }
    
    declare const inputPath: string;
    
    const parsed = parsePath(inputPath);
    //    ^? const parsed: AbsoluteParsedPath | RelativeParsedPath
    
    if (parsed.isAbsolute) {
      parsed
      //^? const parsed: AbsoluteParsedPath
    } else {
      parsed
      //^? const parsed: RelativeParsedPath
    }