Skip to content

Commit

Permalink
✨ Add startsWith and endsWith functions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Apr 16, 2021
1 parent fe90ccf commit 11270ab
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/endsWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { isString } from '@/isString'
import { StringWith } from '@/startsWith'

type endsWith<T extends string | undefined = undefined> = StringWith<
'endsWith',
T
>

/**
* Checks if a string ends with the provided substring.
* @param val - search string
* @param target - target string
* @returns The result of `target.endsWith(val)`
*
* @example
* Basic
* endsWith('world', 'hello world') // true
* endsWith('earth', 'hello world') // false
*
* @example
* Curry
* const endsWithTs = endsWith('ts')
* endsWithTs('index.ts') // true
*/
const endsWith = <T extends string, U extends string | undefined = undefined>(
val: T,
target?: U
): endsWith<U> => {
if (isString(target)) {
return target.endsWith(val) as endsWith<U>
}
return ((_target: string) => endsWith(val, _target)) as endsWith<U>
}

export { endsWith }
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { isString } from '@/isString'
export type { IsSymbol } from '@/isSymbol'
export { isSymbol } from '@/isSymbol'
export { multiply } from '@/multiply'
export { startsWith } from '@/startsWith'
export { subtract } from '@/subtract'
export { toLower } from '@/toLower'
export { toUpper } from '@/toUpper'
Expand Down
42 changes: 42 additions & 0 deletions src/startsWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { isString } from '@/isString'

type StringWith<
T extends 'startsWith' | 'endsWith',
U extends string | undefined = undefined
> = U extends undefined
? (target: string) => ReturnType<string[T]>
: ReturnType<string[T]>

type StartsWith<T extends string | undefined = undefined> = StringWith<
'startsWith',
T
>

/**
* Checks if a string starts with the provided substring.
* @param val - search string
* @param target - target string
* @returns The result of `target.startsWith(val)`
*
* @example
* Basic
* startsWith('hello', 'hello world') // true
* startsWith('good', 'hello world') // false
*
* @example
* Curry
* const startWithSlash = startsWith('/')
* startWithSlash('/path/to') // true
*/
const startsWith = <T extends string, U extends string | undefined = undefined>(
val: T,
target?: U
): StartsWith<U> => {
if (isString(target)) {
return target.startsWith(val) as StartsWith<U>
}
return ((_target: string) => startsWith(val, _target)) as StartsWith<U>
}

export { startsWith }
export type { StringWith }
16 changes: 16 additions & 0 deletions test/endsWith.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { endsWith } from '@/endsWith'

describe('endsWith', () => {
const table: [string, string, boolean][] = [
['', '', true],
['o', 'hello', true],
['world', 'hello world', true],
['O', 'hello', false],
['earth', 'hello world', false],
['Hello', 'hello', false]
]

it.each(table)('endsWith(%s, %s) -> %s', (val, target, expected) => {
expect(endsWith(val, target)).toBe(expected)
})
})
14 changes: 14 additions & 0 deletions test/starsWith.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { startsWith } from '@/startsWith'

describe('startsWith', () => {
const table: [string, string, boolean][] = [
['', '', true],
['hello', 'hello world', true],
['H', 'hello', false],
['Hello', 'hello', false]
]

it.each(table)('startsWith(%s, %s) -> %s', (val, target, expected) => {
expect(startsWith(val, target)).toBe(expected)
})
})

0 comments on commit 11270ab

Please sign in to comment.