Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

S.Length<S extends String> #158

Open
MattRCole opened this issue Nov 21, 2020 · 2 comments
Open

S.Length<S extends String> #158

MattRCole opened this issue Nov 21, 2020 · 2 comments
Assignees
Labels
feature Add new features
Projects

Comments

@MattRCole
Copy link

MattRCole commented Nov 21, 2020

馃崺 Feature Request

Is your feature request related to a problem?

It is extremely difficult to derive the length of a string using typescript typings.

Unlike the relatively simple way one can get the length of an array:

type Length<T extends Array> = T['length']

type Test = Length<['a', 'b', 'c']> // Test = 3

The length of a string is very hard to determine

type Length<S extends String> = S['length']

type Test = Length<'abc'> // Test = number

Describe the solution you'd like

A first stab at a solution:

type EmptyString = ''
type NonEmptyString<S extends string> = S extends EmptyString
  ? never
  : S

type SingleChar<S extends string> = S extends `${NonEmptyString<infer X>}${NonEmptyString<infer Y>}`
  ? false
  : true


type Head<S extends string> =
  S extends `${infer X}${string}`
  ? SingleChar<X> extends true
    ? X
    : never
  : never

type Tail<S extends string> =
  S extends `${infer X}${infer Tail}`
  ? SingleChar<X> extends true
    ? Tail
    : never
  : never

type HasTail<S extends string> =
  Tail<S> extends EmptyString
  ? false
  : true

type __Length<S extends string, I extends any[] = []> = {
  0: __Length<Tail<S>, Next<I>>
  1: L.Length<I>
}[
  Tail<S> extends EmptyString
  ? 1
  : 0
]

type _Length<S extends string> =
  S extends EmptyString
  ? 0
  : __Length<S> extends infer X
    ? Increment<Cast<X, number>> // Increment here would probably be something like N.Plus<`${Cast<X, number>}`, '1', 'n'>
    : never

type Length<S extends string> =
  _Length<S> extends infer X
  ? Cast<X, number>
  : never

type Test0 = Length<'abc'> // Test0 = 3
type Test1 = Length<''>       // Test1 = 0

This type might be too "beefy" though and could probably be cut down. It also requires the use of TS 4.1.

Describe alternatives you've considered

I've considered putting in a pull request, but the proposed solution probably needs a lot work, so I've made this feature suggestion instead.

Teachability, Documentation, Adoption, Migration Strategy

A function description would probably be sufficient:

Returns the length of S as a Number

Edit: Clarity

@millsp
Copy link
Owner

millsp commented Nov 22, 2020

Hey @MattRCole,

I would be all in for such a utility. You had a good practise there with the type system there, well done! But I think that we can indeed do shorter by shipping a Split type that will split on '' empty strings and then we can retrieve the length from there - just to keep it all more generic.

@millsp millsp added the feature Add new features label Nov 22, 2020
@stale stale bot added the wontfix This will not be worked on label Jan 23, 2021
Repository owner deleted a comment from stale bot Jan 23, 2021
@stale stale bot removed the wontfix This will not be worked on label Jan 23, 2021
@millsp millsp added this to To do in Board via automation Jan 29, 2021
@millsp millsp moved this from To do to Done in Board Jan 30, 2021
@millsp millsp closed this as completed Feb 2, 2021
@millsp millsp reopened this May 26, 2021
Board automation moved this from Done to In progress May 26, 2021
@stale
Copy link

stale bot commented Jul 30, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Jul 30, 2021
@stale stale bot closed this as completed Aug 18, 2021
Board automation moved this from In progress to Done Aug 18, 2021
@millsp millsp reopened this Sep 3, 2021
Board automation moved this from Done to In progress Sep 3, 2021
@stale stale bot removed the wontfix This will not be worked on label Sep 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Add new features
Projects
Board
  
In progress
Development

No branches or pull requests

2 participants