Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type {DistributedPick} from './source/distributed-pick';
export type {EmptyObject, IsEmptyObject} from './source/empty-object';
export type {IfEmptyObject} from './source/if-empty-object';
export type {NonEmptyObject} from './source/non-empty-object';
export type {NonEmptyString} from './source/non-empty-string';
export type {UnknownRecord} from './source/unknown-record';
export type {UnknownArray} from './source/unknown-array';
export type {Except} from './source/except';
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ Click the type names for complete docs.
- [`And`](source/and.d.ts) - Returns a boolean for whether two given types are both true.
- [`Or`](source/or.d.ts) - Returns a boolean for whether either of two given types are true.
- [`NonEmptyTuple`](source/non-empty-tuple.d.ts) - Matches any non-empty tuple.
- [`NonEmptyString`](source/non-empty-string.d.ts) - Matches any non-empty string.
- [`FindGlobalType`](source/find-global-type.d.ts) - Tries to find the type of a global with the given name.
- [`FindGlobalInstanceType`](source/find-global-type.d.ts) - Tries to find one or more types from their globally-defined constructors.

Expand Down
28 changes: 28 additions & 0 deletions source/non-empty-string.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
Matches any non-empty string.

This is useful when you need a string that is not empty, for example, as a function parameter.

NOTE:
- This returns `never` not just when instantiated with empty string, but also when empty string is a subtype of the instantiated type, like `string` or `Uppercase<string>`.

@example
```
import type {NonEmptyString} from 'type-fest';

declare function foo<T extends string>(string: NonEmptyString<T>): void;

foo('a');
//=> OK

foo('');
//=> Error: Argument of type '""' is not assignable to parameter of type 'never'.

declare const someString: string
foo(someString);
//=> Error: Argument of type 'string' is not assignable to parameter of type 'never'.
```

@category String
*/
export type NonEmptyString<T extends string> = '' extends T ? never : T;
25 changes: 25 additions & 0 deletions test-d/non-empty-string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {expectType} from 'tsd';
import type {NonEmptyString} from '../index';

expectType<never>({} as NonEmptyString<''>);

expectType<'a'>({} as NonEmptyString<'a'>);

expectType<never>({} as NonEmptyString<string>);
expectType<never>({} as NonEmptyString<Uppercase<string>>);
expectType<`on${string}`>({} as NonEmptyString<`on${string}`>);

expectType<'a' | 'b'>({} as NonEmptyString<'a' | 'b'>);
expectType<'a' | `${number}.${number}`>({} as NonEmptyString<'a' | `${number}.${number}`>);
expectType<never>({} as NonEmptyString<'' | 'a'>);
expectType<never>({} as NonEmptyString<'a' | Uppercase<string>>);
expectType<never>({} as NonEmptyString<'' | `on${string}`>);

// `NonEmptyString<S>` should be assignable to `string`
type Assignability1<_S extends string> = unknown;
type Test1<S extends string> = Assignability1<NonEmptyString<S>>;

// `string` should NOT be assignable to `NonEmptyString<S>`
type Assignability2<_S extends string, _SS extends NonEmptyString<_S>> = unknown;
// @ts-expect-error
type Test2<S extends string> = Assignability2<S, S>;