Skip to content

Commit ed088ba

Browse files
committed
🐛 Improve type inference
1 parent 4dabc80 commit ed088ba

File tree

8 files changed

+107
-80
lines changed

8 files changed

+107
-80
lines changed

common/init.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
2+
import { slice } from '../deps.ts'
3+
4+
/**
5+
* @example
6+
* ```ts
7+
* InitString<string> // string
8+
* InitString<''> // ''
9+
* InitString<'a'> // ''
10+
* InitString<'ab'> // 'a'
11+
* InitString<'abcd'> // 'abc'
12+
* ```
13+
* @internal
14+
*/
15+
type InitString<T extends string> = T extends `${infer F}${infer R}`
16+
? R extends ''
17+
? ''
18+
: `${F}${InitString<R>}`
19+
: T extends ''
20+
? ''
21+
: string
22+
23+
/**
24+
* Infer the init types.
25+
* @typeParam T - `string` or any `array`
26+
*
27+
* @example
28+
* ```ts
29+
* // String
30+
* Init<string> // string
31+
* Init<''> // ''
32+
* Init<'hello'> // 'hell'
33+
* ```
34+
*
35+
* @example
36+
* ```ts
37+
* // Array
38+
* Init<[] | never[] | readonly [] | readonly never[]> // []
39+
* Init<['hello', 'world']> // 'hello'
40+
* ```
41+
*
42+
* @category `Array` `String`
43+
*
44+
* @see Related to {@link First}
45+
*
46+
* @public
47+
*/
48+
type Init<T extends string | readonly unknown[]> = T extends string
49+
? InitString<T>
50+
: T extends readonly never[] | []
51+
? []
52+
: T extends readonly [...infer I, unknown]
53+
? I
54+
: T
55+
56+
/**
57+
* Returns all but the init element of the given list or string.
58+
* @param val - string or any array object
59+
* @returns The result of `val.slice(0, -1)`
60+
*
61+
* @example
62+
* ```ts
63+
* // String
64+
* init('hello') // 'hell'
65+
* init('h') // ''
66+
* init('') // ''
67+
* ```
68+
*
69+
* @example
70+
* ```ts
71+
* init([1, 2, 3]) // [1, 2]
72+
* init(['hello', 'world']) // ['hello']
73+
* init(['hello']) // []
74+
* init([]) // []
75+
* ```
76+
*
77+
* @category `Array` `String`
78+
*
79+
* @see Related to {@link tail}
80+
*
81+
* @public
82+
*/
83+
const init = <T extends string | readonly unknown[]>(val: T): Init<T> =>
84+
slice(0, -1, val) as Init<T>
85+
86+
export { init }
87+
export type { Init }
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
2-
import { assertEquals } from '../dev_deps.ts'
3-
import { init } from '../src/init.ts'
2+
import { assertEquals, assertEqualsType } from '../dev_deps.ts'
3+
import { Init, init } from './init.ts'
44

55
Deno.test('init', () => {
66
const tableString: [string, string][] = [
@@ -37,4 +37,14 @@ Deno.test('init', () => {
3737
tableArray.forEach(([val, expected]) => {
3838
assertEquals(init(val), expected, `init(${val}) -> ${expected}`)
3939
})
40+
41+
assertEqualsType<[], Init<[]>>()
42+
assertEqualsType<readonly [], Init<readonly []>>()
43+
assertEqualsType<[], Init<[1]>>()
44+
assertEqualsType<[1], Init<[1, 2]>>()
45+
assertEqualsType<[1, 2], Init<[1, 2, 3]>>()
46+
assertEqualsType<'', Init<''>>()
47+
assertEqualsType<'', Init<'a'>>()
48+
assertEqualsType<'a', Init<'ab'>>()
49+
assertEqualsType<'abcde', Init<'abcdef'>>()
4050
})

common/mod.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
22
export type { Head } from './head.ts'
33
export { head } from './head.ts'
4+
export type { Init } from './init.ts'
5+
export { init } from './init.ts'
46
export type { Last } from './last.ts'
57
export { last } from './last.ts'

deps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
2-
export { length } from 'https://deno.land/x/core_fn@v1.0.0-beta.8/mod.ts'
2+
export { length } from 'https://deno.land/x/core_fn@v1.0.0-beta.14/mod.ts'
3+
export { slice } from 'https://deno.land/x/core_fn@v1.0.0-beta.14/uncurry/common/slice.ts'
34
export { curry } from 'https://deno.land/x/curry@v1.0.0/mod.ts'
45
export { equal } from 'https://deno.land/x/equal@v1.5.0/mod.ts'
56
export {

dev_deps.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
2+
/* eslint-disable @typescript-eslint/no-empty-function */
3+
/* eslint-disable @typescript-eslint/no-unused-vars */
4+
25
export {
36
assert,
47
assertEquals
58
} from 'https://deno.land/std@0.97.0/testing/asserts.ts'
9+
export const assertEqualsType = <T, U extends T = T>(_actual?: U): void => {}
610
export { length } from 'https://deno.land/x/core_fn@v1.0.0-beta.8/mod.ts'
711
export {
812
isNumber,

mod.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export { identity } from './src/identity.ts'
2222
export { ifElse } from './src/ifElse.ts'
2323
export { ifElseFn } from './src/ifElseFn.ts'
2424
export { inc } from './src/inc.ts'
25-
export { init } from './src/init.ts'
2625
export { K } from './src/K.ts'
2726
export { lt } from './src/lt.ts'
2827
export { lte } from './src/lte.ts'

src/init.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

test/init.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)