|
| 1 | +import {expectType} from 'tsd'; |
| 2 | +import type {RemovePrefix} from '../source/remove-prefix.d.ts'; |
| 3 | + |
| 4 | +expectType<'change'>({} as RemovePrefix<'on-change', 'on-'>); |
| 5 | +expectType<'Click'>({} as RemovePrefix<'handleClick', 'handle'>); |
| 6 | +expectType<'vscode'>({} as RemovePrefix<'.vscode', '.'>); |
| 7 | +expectType<'whitespace'>({} as RemovePrefix<' whitespace', ' '>); |
| 8 | + |
| 9 | +// Prefix not present |
| 10 | +expectType<''>({} as RemovePrefix<'', 'foo'>); |
| 11 | +expectType<'on-mouse-move'>({} as RemovePrefix<'on-mouse-move', 'click'>); |
| 12 | + |
| 13 | +// Empty prefix |
| 14 | +expectType<'baz'>({} as RemovePrefix<'baz', ''>); |
| 15 | + |
| 16 | +// Prefix completely matches the input string |
| 17 | +expectType<''>({} as RemovePrefix<'click', 'click'>); |
| 18 | + |
| 19 | +// Prefix partially matches the input string |
| 20 | +expectType<'foobar'>({} as RemovePrefix<'foobar', 'foobaz'>); |
| 21 | +expectType<'hello'>({} as RemovePrefix<'hello', 'helloworld'>); |
| 22 | + |
| 23 | +// Multiple occurrences of prefix (should only remove from start) |
| 24 | +expectType<'bar-bar-foo'>({} as RemovePrefix<'bar-bar-bar-foo', 'bar-'>); |
| 25 | +expectType<'foofoo'>({} as RemovePrefix<'foofoofoo', 'foo'>); |
| 26 | + |
| 27 | +// === Non-literals === |
| 28 | + |
| 29 | +// Input: Non-literal, Prefix: Literal |
| 30 | +expectType<string>({} as RemovePrefix<`hover:${string}`, 'hover:'>); |
| 31 | +expectType<Capitalize<string>>({} as RemovePrefix<`on${Capitalize<string>}`, 'on'>); |
| 32 | +expectType<`${number}`>({} as RemovePrefix<`id-${number}`, 'id-'>); |
| 33 | +expectType<`${string}--`>({} as RemovePrefix<`--${string}--`, '--'>); |
| 34 | +expectType<`focus:${string}`>({} as RemovePrefix<`hover:focus:${string}`, 'hover:'>); |
| 35 | +expectType<`user_${string}`>({} as RemovePrefix<`user_${string}`, 'admin_'>); |
| 36 | +expectType<string>({} as RemovePrefix<string, 'on'>); |
| 37 | +expectType<`${string}/${number}`>({} as RemovePrefix<`${string}/${number}`, 'foo'>); |
| 38 | + |
| 39 | +// Input: Literal, Prefix: Non-literal |
| 40 | +expectType<string>({} as RemovePrefix<'on-click', `${string}-`>); |
| 41 | +expectType<string>({} as RemovePrefix<'hover:flex', string>); |
| 42 | +expectType<'handle-click'>({} as RemovePrefix<'handle-click', Uppercase<string>>); |
| 43 | +expectType<'on-change'>({} as RemovePrefix<'on-change', `${string}--`>); |
| 44 | + |
| 45 | +// Input: Non-literal, Prefix: Non-literal |
| 46 | +expectType<string>({} as RemovePrefix<`hover:${string}`, `${string}:`>); |
| 47 | +expectType<string>({} as RemovePrefix<`${string}/${number}`, `${string}/`>); |
| 48 | +expectType<string>({} as RemovePrefix<string, string>); |
| 49 | +expectType<`${string}/${number}`>({} as RemovePrefix<`${string}/${number}`, `${string}:`>); |
| 50 | +expectType<`${number}:${number}`>({} as RemovePrefix<`${number}:${number}`, `-${string}`>); |
| 51 | + |
| 52 | +// Unions |
| 53 | +expectType<'click' | 'hover' | 'change'>({} as RemovePrefix<'on-click' | 'on-hover' | 'on-change', 'on-'>); |
| 54 | +expectType<'click' | 'hover' | 'handle-change'>({} as RemovePrefix<'on-click' | 'on-hover' | 'handle-change', 'on-'>); |
| 55 | +expectType<Uppercase<string> | `${number}`>({} as RemovePrefix<`id-${Uppercase<string>}` | `id-${number}`, 'id-'>); |
| 56 | +expectType<string>({} as RemovePrefix<`hover:${string}` | `focus:${string}`, `${string}:`>); |
| 57 | + |
| 58 | +expectType<'-change' | 'change'>({} as RemovePrefix<'on-change', 'on' | 'on-'>); |
| 59 | +expectType<'change' | 'on-change'>({} as RemovePrefix<'on-change', 'on-' | 'handle-'>); |
| 60 | +expectType<'on-change'>({} as RemovePrefix<'on-change', 'off-' | 'handle-'>); |
| 61 | +expectType<string>({} as RemovePrefix<'on-change', `${string}-` | 'on'>); |
| 62 | + |
| 63 | +expectType<'on:change' | 'onChange'>({} as RemovePrefix<'on:change' | 'onChange', `${string}-`>); |
| 64 | +expectType<'name' | 'get-name' | 'age' | 'set-age' | 'other'>( |
| 65 | + {} as RemovePrefix<'get-name' | 'set-age' | 'other', 'get-' | 'set-'>, |
| 66 | +); |
| 67 | +expectType<string>({} as RemovePrefix<`id:${Uppercase<string>}` | `id/${number}`, `${string}:` | `${string}/`>); |
| 68 | + |
| 69 | +// Boundary types |
| 70 | +expectType<any>({} as RemovePrefix<any, 'foo'>); |
| 71 | +expectType<never>({} as RemovePrefix<never, 'foo'>); |
| 72 | +expectType<string>({} as RemovePrefix<'on-change', any>); |
| 73 | +expectType<'on-change'>({} as RemovePrefix<'on-change', never>); |
| 74 | + |
| 75 | +// === strict: false === |
| 76 | + |
| 77 | +// No effect if `Prefix` is a literal |
| 78 | +expectType<'change'>({} as RemovePrefix<'on-change', 'on-', {strict: false}>); |
| 79 | +expectType<'change' | 'hover'>({} as RemovePrefix<'on-change' | 'on-hover', 'on-', {strict: false}>); |
| 80 | +expectType<Capitalize<string>>({} as RemovePrefix<`handle${Capitalize<string>}`, 'handle', {strict: false}>); |
| 81 | + |
| 82 | +expectType<'click'>({} as RemovePrefix<'on-click', `${string}-`, {strict: false}>); |
| 83 | +expectType<'over:flex'>({} as RemovePrefix<'hover:flex', string, {strict: false}>); |
| 84 | +expectType<`${number}`>({} as RemovePrefix<`${string}/${number}`, `${string}/`, {strict: false}>); |
| 85 | +expectType<'change' | '-change'>({} as RemovePrefix<'on-change', `${string}-` | 'on', {strict: false}>); |
| 86 | +expectType<'on:change' | 'change'>({} as RemovePrefix<'on:change' | 'on-change', `${string}-`, {strict: false}>); |
| 87 | +expectType<Uppercase<string> | `id:${Uppercase<string>}` | `${number}` | `id/${number}`>( |
| 88 | + {} as RemovePrefix<`id:${Uppercase<string>}` | `id/${number}`, `${string}:` | `${string}/`, {strict: false}>, |
| 89 | +); |
| 90 | + |
| 91 | +// Generic assignability test |
| 92 | +type Assignability<S extends string> = S; |
| 93 | +// Output of `RemovePrefix` should be assignable to `string`. |
| 94 | +type Test1<S extends string, Prefix extends string> = Assignability<RemovePrefix<S, Prefix>>; |
| 95 | +type Test2<S extends Uppercase<string>, Prefix extends '-' | '/' | '#'> = Assignability<RemovePrefix<S, Prefix>>; |
0 commit comments