Git Product home page Git Product logo

typed-path's Introduction

Typed Path

https://nodei.co/npm/typed-path.svg?downloads=true&downloadRank=true&stars=true

Travis Hits Contributions welcome GitHub top language David npm bundle size GitHub last commit Snyk Vulnerabilities for GitHub Repo GitHub issues Code Climate maintainability Code Climate technical debt codecov

Overview

This small utility helps to extract type information from a TypeScript class, interface or type to use it in your code.

Example:

import {typedPath} from 'typed-path';

type TestType = {
    a: {
        testFunc: () => {result: string};
        b: {
            arrayOfArrays: string[][];
            c: {
                d: number;
            };
        }[];
    };
};

console.log(typedPath<TestType>().a.b[5].c.d.$rawPath);
/*
Outputs
["a", "b", 5, "c", "d"]

*/

Please see other path access methods and how to add custom path access methods below.

The utility might also be used to add type protection to such methods as _.get, _.map, _.set, R.pluck from libraries like lodash, ramda.

It is recommended, though, to use optional chaining instead.


Features

Errors

With typed-path, typescript can check paths and warns you about errors.

Path access methods

Default

.$path

@m-abboud
Also, you can get access to the path string using $path special field.

Like this:

    console.log(tp<TestType>().a.b.c.d.$path); // this will output "a.b.c.d"
.$raw

@dcbrwn
If you need a raw path, which is of type string[] - you can get it using $raw special field.
Deprecated, since it transforms symbols and numbers to strings, which might be not an expected behavior (the method name is "raw"). Please use .$rawPath

    console.log(tp<TestType>().a.b.c.d.$raw); // this will output ["a", "b", "c", "d"]
.$rawPath

If you need a raw path, which is of type (string | number | Symbol)[] - you can get it using $rawPath special field.

    console.log(tp<TestType>().a.b[5].c.d.$rawPath); // this will output ["a", "b", 5, "c", "d"]

The $rawPath is something that you might want to use with the following methods from Ramda, to add type safety on the path:

Example: https://codesandbox.io/s/typed-path-ramda-assoc-path-x3qby?file=/src/index.ts

Additional handlers

@nick-lvov-dev

You can extend path handlers functionality using additional handlers:

const testAdditionalHandlers = {
    $url: (path: TypedPathKey[]) => path.join('/')
}

console.log(tp<TestType, typeof testAdditionalHandlers>(testAdditionalHandlers).a.b.c.$url); // this will output "a/b/c"

The additional handlers are also chainable:

const testAdditionalHandlers = {
    $abs: (path: TypedPathKey[]) => typedPath<TestType, typeof testAdditionalHandlers>(testAdditionalHandlers, ['', ...path]),
    $url: (path: TypedPathKey[]) => path.join('/'),
    $length: (path: TypedPathKey[]) => path.length
}

console.log(tp<TestType, typeof testAdditionalHandlers>(testAdditionalHandlers).a.b.c.$abs.$url); // this will output "/a/b/c"

Suggestions

Also, typed-path allows typescript to suggest field names for you.

License

Copyright (c) 2021 Oleksandr Beshchuk <[email protected]>
Licensed under the Apache License.

typed-path's People

Contributors

aleut avatar bsalex avatar dependabot[bot] avatar funkydck avatar m-abboud avatar nick-lvov-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

typed-path's Issues

How to define typedPath return type?

Hi!

I need to define generic return type of typedPath function. I see it returns TypedPathWrapper, which mentions DefaultHandlers. I tried ReturnType<typeof typedPath>, but in this case it's not generic and displayed as any. If I use TypedPathWrapper - it requires 2 options, first is type itself and second is handlers. But if I use default handlers, I need DefaultHandlers, but it's not explorted. I suggest to export DefaultHandlers. Currently I use it like export type TPWrapper<T> = TypedPathWrapper<DeepRequired<T>, any>;

TypeScript error after upgrade to TS 5.3.3

Type '(target: T, name: TypedPathKey) => any' is not assignable to type '(target: {}, p: string | symbol, receiver: any) => any'.
  Types of parameters 'target' and 'target' are incompatible.
    Type '{}' is not assignable to type 'T'.
      'T' could be instantiated with an arbitrary type which could be unrelated to '{}'.  TS2322

for the following line:

get(target: T, name: TypedPathKey) {

Some improvement ideas

First of all, thanks for sharing your smart idea!

But, IMO, to be used in production, it requires some important improvements:

  1. It should be implemented as a typescript module and re-export only typedPath function in index.ts. The implementation detail should be private and placed in separated files.
  2. Currently, separator is hard-coded as a dot. In real life, we also want to use slash / to build url or file path. So the separator should be configurable.
  3. How to insert a dynamic value in the middle of the path? For example, how can we build url /users/:username/posts/:postId/comments?

Best regards

$raw support numbered indexes for ramda

Currently, using an index field with ramda can cause some confusion:

tp<typeof state>().array[index].x.y.$raw

This produces a path of ['array', index.toString(), 'x', 'y']. This causes problems in ramda since it looks to the path type to determine array or object. This will cause something like assocPath to turn an array into an object.

Reference original type while accessing lower on the proxy

I have a case where I'd like to pass typedPath<Something>().a.b.c to a method/class and be able to still reference the type Something later on.

Ideally, I only want to accept a path "derived from" Something in a class or method.

How might I go about doing this? Any ideas?

Support optional properties.

It's common for properties of Typescript interfaces to be optional:

interface Thing {
  foo: string;
  bar?: string;
}

typedPath<Thing>().bar.$path raises an Object is possibly 'undefined' error, when that's probably not desireable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.