-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #96 from poteat/poteat/further-reified-types
Add string case reified types
- Loading branch information
Showing
22 changed files
with
1,291 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { $, Test, String } from '..' | ||
|
||
type CamelCase_Spec = [ | ||
/** | ||
* Can convert a string to camelCase. | ||
*/ | ||
Test.Expect<$<String.CamelCase, 'hello world'>, 'helloWorld'>, | ||
|
||
/** | ||
* Can convert a string with multiple words. | ||
*/ | ||
Test.Expect<$<String.CamelCase, 'hello world 42'>, 'helloWorld42'>, | ||
|
||
/** | ||
* Can convert a string with acronyms. | ||
*/ | ||
Test.Expect<$<String.CamelCase, 'XMLHttpRequest'>, 'xmlHttpRequest'>, | ||
|
||
/** | ||
* Can convert a string with numbers. | ||
*/ | ||
Test.Expect<$<String.CamelCase, 'hello42world'>, 'hello42World'>, | ||
|
||
/** | ||
* Can convert a string with a mix of words and numbers. | ||
*/ | ||
Test.Expect<$<String.CamelCase, 'hello42world 42'>, 'hello42World42'>, | ||
|
||
/** | ||
* Can handle an empty string. | ||
*/ | ||
Test.Expect<$<String.CamelCase, ''>, ''> | ||
] | ||
|
||
it('should convert a string to camelCase', () => { | ||
expect(String.camelCase('hello world')).toBe('helloWorld') | ||
}) | ||
|
||
it('should convert a string with multiple words', () => { | ||
expect(String.camelCase('hello world 42')).toBe('helloWorld42') | ||
}) | ||
|
||
it('should convert a string with acronyms', () => { | ||
expect(String.camelCase('XMLHttpRequest')).toBe('xmlHttpRequest') | ||
}) | ||
|
||
it('should convert a string with numbers', () => { | ||
expect(String.camelCase('hello42world')).toBe('hello42World') | ||
}) | ||
|
||
it('should convert a string with a mix of words and numbers', () => { | ||
expect(String.camelCase('hello42world 42')).toBe('hello42World42') | ||
}) | ||
|
||
it('should handle an empty string', () => { | ||
expect(String.camelCase('')).toBe('') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Kind, Type, String } from '..' | ||
|
||
/** | ||
* `_$camelCase` is a type-level function that takes in a string `S` and returns | ||
* a new string in the "camelCase" format, whereby the first letter of each word | ||
* is capitalized, except for the first word. Capitalized acronyms in the input | ||
* are identified. | ||
* | ||
* @template {string} S - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { String } from "hkt-toolbelt"; | ||
* | ||
* type Result = String._$camelCase<'hello world'>; // 'helloWorld' | ||
* ``` | ||
*/ | ||
export type _$camelCase< | ||
S extends string, | ||
WORDS extends string[] = String._$words<S> | ||
> = String._$fromList<{ | ||
[K in keyof WORDS]: K extends '0' | ||
? String._$toLower<WORDS[K]> | ||
: String._$capitalize<String._$toLower<WORDS[K]>> | ||
}> | ||
|
||
/** | ||
* `CamelCase` is a type-level function that takes in a string `S` and returns | ||
* a new string in the "camelCase" format, whereby the first letter of each word | ||
* is capitalized, except for the first word. Capitalized acronyms in the input | ||
* are identified. | ||
* | ||
* @template {string} S - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { $, String } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<String.CamelCase, 'hello world'>; // 'helloWorld' | ||
* ``` | ||
*/ | ||
export interface CamelCase extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], string>): _$camelCase<typeof x> | ||
} | ||
|
||
/** | ||
* Given a string, return a new string in the "camelCase" format, whereby the | ||
* first letter of each word is capitalized, except for the first word. | ||
* | ||
* @param {string} x - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { String } from "hkt-toolbelt"; | ||
* | ||
* const result = String.camelCase('hello world') | ||
* // ^? 'helloWorld' | ||
* ``` | ||
*/ | ||
export const camelCase = ((x: string) => | ||
String.words(x) | ||
.map((word, i) => | ||
i === 0 ? word.toLowerCase() : String.capitalize(word.toLowerCase()) | ||
) | ||
.join('')) as Kind._$reify<CamelCase> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { $, Test, String } from '..' | ||
|
||
type ConstantCase_Spec = [ | ||
/** | ||
* Can convert a string to CONSTANT_CASE. | ||
*/ | ||
Test.Expect<$<String.ConstantCase, 'hello world'>, 'HELLO_WORLD'>, | ||
|
||
/** | ||
* Can convert a string with multiple words. | ||
*/ | ||
Test.Expect<$<String.ConstantCase, 'hello world 42'>, 'HELLO_WORLD_42'>, | ||
|
||
/** | ||
* Can convert a string with acronyms. | ||
*/ | ||
Test.Expect<$<String.ConstantCase, 'XMLHttpRequest'>, 'XML_HTTP_REQUEST'>, | ||
|
||
/** | ||
* Can convert a string with numbers. | ||
*/ | ||
Test.Expect<$<String.ConstantCase, 'hello42world'>, 'HELLO_42_WORLD'> | ||
] | ||
|
||
it('should convert a string to CONSTANT_CASE', () => { | ||
expect(String.constantCase('hello world')).toBe('HELLO_WORLD') | ||
}) | ||
|
||
it('should convert a string with multiple words', () => { | ||
expect(String.constantCase('hello world 42')).toBe('HELLO_WORLD_42') | ||
}) | ||
|
||
it('should convert a string with acronyms', () => { | ||
expect(String.constantCase('XMLHttpRequest')).toBe('XML_HTTP_REQUEST') | ||
}) | ||
|
||
it('should convert a string with numbers', () => { | ||
expect(String.constantCase('hello42world')).toBe('HELLO_42_WORLD') | ||
}) | ||
|
||
it('should handle an empty string', () => { | ||
expect(String.constantCase('')).toBe('') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Kind, Type, String as String_ } from '..' | ||
|
||
/** | ||
* `_$constantCase` is a type-level function that takes in a string `S` and returns | ||
* a new string in the "CONSTANT_CASE" format, whereby each word is uppercased | ||
* and separated by underscores. | ||
* | ||
* @template {string} S - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { String } from "hkt-toolbelt"; | ||
* | ||
* type Result = String._$constantCase<'hello world'>; // 'HELLO_WORLD' | ||
* ``` | ||
*/ | ||
export type _$constantCase< | ||
S extends string, | ||
WORDS extends string[] = String_._$words<S> | ||
> = String_._$join< | ||
{ | ||
[K in keyof WORDS]: String_._$toUpper<WORDS[K]> | ||
}, | ||
'_' | ||
> | ||
|
||
/** | ||
* `ConstantCase` is a type-level function that takes in a string `S` and returns | ||
* a new string in the "CONSTANT_CASE" format, whereby each word is uppercased | ||
* and separated by underscores. | ||
* | ||
* @template {string} S - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { $, String } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<String.ConstantCase, 'hello world'>; // 'HELLO_WORLD' | ||
* ``` | ||
*/ | ||
export interface ConstantCase extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], string>): _$constantCase<typeof x> | ||
} | ||
|
||
/** | ||
* Given a string, return a new string in the "CONSTANT_CASE" format, whereby | ||
* each word is uppercased and separated by underscores. | ||
* | ||
* @param {string} x - The string to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { String } from "hkt-toolbelt"; | ||
* | ||
* const result = String.constantCase('hello world') | ||
* // ^? 'HELLO_WORLD' | ||
* ``` | ||
*/ | ||
export const constantCase = ((x: string) => | ||
String_.words(x) | ||
.map((word) => word.toUpperCase()) | ||
.join('_')) as Kind._$reify<ConstantCase> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,37 @@ | ||
export * from './append' | ||
export * from './camel-case' | ||
export * from './capitalize' | ||
export * from './constant-case' | ||
export * from './ends-with' | ||
export * from './entries' | ||
export * from './first' | ||
export * from './from-char-code' | ||
export * from './from-list' | ||
export * from './includes' | ||
export * from './init' | ||
export * from './is-digit' | ||
export * from './is-letter' | ||
export * from './is-lowercase-letter' | ||
export * from './is-string' | ||
export * from './is-template' | ||
export * from './is-uppercase-letter' | ||
export * from './join' | ||
export * from './kebab-case' | ||
export * from './last' | ||
export * from './length' | ||
export * from './pad-end' | ||
export * from './pad-start' | ||
export * from './pascal-case' | ||
export * from './prepend' | ||
export * from './replace' | ||
export * from './reverse' | ||
export * from './slice' | ||
export * from './snake-case' | ||
export * from './split' | ||
export * from './starts-with' | ||
export * from './tail' | ||
export * from './to-char-code' | ||
export * from './to-list' | ||
export * from './to-lower' | ||
export * from './to-upper' | ||
export * from './words' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { $, String, Test } from '..' | ||
|
||
type IsDigit_Spec = [ | ||
/** | ||
* Can check if a string is a digit. | ||
*/ | ||
Test.Expect<$<String.IsDigit, '0'>, true>, | ||
|
||
/** | ||
* Can check if a string is a digit | ||
*/ | ||
Test.Expect<$<String.IsDigit, '9'>, true>, | ||
|
||
/** | ||
* Can check if a string is not a digit. | ||
*/ | ||
Test.Expect<$<String.IsDigit, 'a'>, false>, | ||
|
||
/** | ||
* An empty string is not a digit. | ||
*/ | ||
Test.Expect<$<String.IsDigit, ''>, false>, | ||
|
||
/** | ||
* A general string is not a digit. | ||
*/ | ||
Test.Expect<$<String.IsDigit, 'foo'>, false>, | ||
|
||
/** | ||
* A template literal string is not a digit. | ||
*/ | ||
Test.Expect<$<String.IsDigit, `0${string}1`>, false> | ||
] | ||
|
||
it('should check if a string is a digit', () => { | ||
expect(String.isDigit('0')).toBe(true) | ||
}) | ||
|
||
it('returns false for an empty string', () => { | ||
expect(String.isDigit('')).toBe(false) | ||
}) | ||
|
||
it('returns false for a general string', () => { | ||
expect(String.isDigit('000')).toBe(false) | ||
}) |
Oops, something went wrong.