type-fest 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -0
- package/package.json +1 -1
- package/readme.md +23 -20
- package/source/delimiter-cased-properties-deep.d.ts +1 -1
- package/source/get.d.ts +10 -4
- package/source/internal.d.ts +7 -0
- package/source/literal-union.d.ts +2 -2
- package/source/partial-deep.d.ts +3 -3
- package/source/pascal-cased-properties-deep.d.ts +1 -1
- package/source/readonly-deep.d.ts +2 -2
- package/source/remove-index-signature.d.ts +98 -0
- package/source/string-key-of.d.ts +25 -0
package/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export {MergeExclusive} from './source/merge-exclusive';
|
|
|
12
12
|
export {RequireAtLeastOne} from './source/require-at-least-one';
|
|
13
13
|
export {RequireExactlyOne} from './source/require-exactly-one';
|
|
14
14
|
export {RequireAllOrNone} from './source/require-all-or-none';
|
|
15
|
+
export {RemoveIndexSignature} from './source/remove-index-signature';
|
|
15
16
|
export {PartialDeep} from './source/partial-deep';
|
|
16
17
|
export {ReadonlyDeep} from './source/readonly-deep';
|
|
17
18
|
export {LiteralUnion} from './source/literal-union';
|
|
@@ -50,6 +51,7 @@ export {
|
|
|
50
51
|
NegativeInteger,
|
|
51
52
|
NonNegativeInteger,
|
|
52
53
|
} from './source/numeric';
|
|
54
|
+
export {StringKeyOf} from './source/string-key-of';
|
|
53
55
|
|
|
54
56
|
// Template literal types
|
|
55
57
|
export {CamelCase} from './source/camel-case';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -99,6 +99,7 @@ Click the type names for complete docs.
|
|
|
99
99
|
- [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys.
|
|
100
100
|
- [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more.
|
|
101
101
|
- [`RequireAllOrNone`](source/require-all-or-none.d.ts) - Create a type that requires all of the given keys or none of the given keys.
|
|
102
|
+
- [`RemoveIndexSignature`](source/remove-index-signature.d.ts) - Create a type that only has explicitly defined properties, absent of any index signatures.
|
|
102
103
|
- [`PartialDeep`](source/partial-deep.d.ts) - Create a deeply optional version of another type. Use [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) if you only need one level deep.
|
|
103
104
|
- [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of an `object`/`Map`/`Set`/`Array` type. Use [`Readonly<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) if you only need one level deep.
|
|
104
105
|
- [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729).
|
|
@@ -118,6 +119,7 @@ Click the type names for complete docs.
|
|
|
118
119
|
- [`SetReturnType`](source/set-return-type.d.ts) - Create a function type with a return type of your choice and the same parameters as the given function type.
|
|
119
120
|
- [`Simplify`](source/simplify.d.ts) - Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
|
120
121
|
- [`Get`](source/get.d.ts) - Get a deeply-nested property from an object using a key path, like [Lodash's `.get()`](https://lodash.com/docs/latest#get) function.
|
|
122
|
+
- [`StringKeyOf`](source/string-key-of.d.ts) - Get keys of the given type as strings.
|
|
121
123
|
|
|
122
124
|
### JSON
|
|
123
125
|
|
|
@@ -162,22 +164,22 @@ Click the type names for complete docs.
|
|
|
162
164
|
|
|
163
165
|
### Change case
|
|
164
166
|
|
|
165
|
-
- [`CamelCase`](source/camel-case.d.ts)
|
|
166
|
-
- [`CamelCasedProperties`](source/camel-cased-properties.d.ts)
|
|
167
|
-
- [`CamelCasedPropertiesDeep`](source/camel-cased-properties-deep.d.ts)
|
|
168
|
-
- [`KebabCase`](source/kebab-case.d.ts)
|
|
169
|
-
- [`KebabCasedProperties`](source/kebab-cased-properties.d.ts)
|
|
170
|
-
- [`KebabCasedPropertiesDeep`](source/kebab-cased-properties-deep.d.ts)
|
|
171
|
-
- [`PascalCase`](source/pascal-case.d.ts)
|
|
172
|
-
- [`PascalCasedProperties`](source/pascal-cased-properties.d.ts)
|
|
173
|
-
- [`PascalCasedPropertiesDeep`](source/pascal-cased-properties-deep.d.ts)
|
|
174
|
-
- [`SnakeCase`](source/snake-case.d.ts)
|
|
175
|
-
- [`SnakeCasedProperties`](source/snake-cased-properties-deep.d.ts)
|
|
176
|
-
- [`SnakeCasedPropertiesDeep`](source/snake-cased-properties-deep.d.ts)
|
|
167
|
+
- [`CamelCase`](source/camel-case.d.ts) - Convert a string literal to camel-case (`fooBar`).
|
|
168
|
+
- [`CamelCasedProperties`](source/camel-cased-properties.d.ts) - Convert object properties to camel-case (`fooBar`).
|
|
169
|
+
- [`CamelCasedPropertiesDeep`](source/camel-cased-properties-deep.d.ts) - Convert object properties to camel-case recursively (`fooBar`).
|
|
170
|
+
- [`KebabCase`](source/kebab-case.d.ts) - Convert a string literal to kebab-case (`foo-bar`).
|
|
171
|
+
- [`KebabCasedProperties`](source/kebab-cased-properties.d.ts) - Convert a object properties to kebab-case recursively (`foo-bar`).
|
|
172
|
+
- [`KebabCasedPropertiesDeep`](source/kebab-cased-properties-deep.d.ts) - Convert object properties to kebab-case (`foo-bar`).
|
|
173
|
+
- [`PascalCase`](source/pascal-case.d.ts) - Converts a string literal to pascal-case (`FooBar`)
|
|
174
|
+
- [`PascalCasedProperties`](source/pascal-cased-properties.d.ts) - Converts object properties to pascal-case (`FooBar`)
|
|
175
|
+
- [`PascalCasedPropertiesDeep`](source/pascal-cased-properties-deep.d.ts) - Converts object properties to pascal-case (`FooBar`)
|
|
176
|
+
- [`SnakeCase`](source/snake-case.d.ts) - Convert a string literal to snake-case (`foo_bar`).
|
|
177
|
+
- [`SnakeCasedProperties`](source/snake-cased-properties-deep.d.ts) - Convert object properties to snake-case (`foo_bar`).
|
|
178
|
+
- [`SnakeCasedPropertiesDeep`](source/snake-cased-properties-deep.d.ts) - Convert object properties to snake-case recursively (`foo_bar`).
|
|
177
179
|
- [`ScreamingSnakeCase`](source/screaming-snake-case.d.ts) - Convert a string literal to screaming-snake-case (`FOO_BAR`).
|
|
178
|
-
- [`DelimiterCase`](source/delimiter-case.d.ts)
|
|
179
|
-
- [`DelimiterCasedProperties`](source/delimiter-cased-properties.d.ts)
|
|
180
|
-
- [`DelimiterCasedPropertiesDeep`](source/delimiter-cased-properties-deep.d.ts)
|
|
180
|
+
- [`DelimiterCase`](source/delimiter-case.d.ts) - Convert a string literal to a custom string delimiter casing.
|
|
181
|
+
- [`DelimiterCasedProperties`](source/delimiter-cased-properties.d.ts) - Convert object properties to a custom string delimiter casing.
|
|
182
|
+
- [`DelimiterCasedPropertiesDeep`](source/delimiter-cased-properties-deep.d.ts) - Convert object properties to a custom string delimiter casing recursively.
|
|
181
183
|
|
|
182
184
|
### Miscellaneous
|
|
183
185
|
|
|
@@ -188,11 +190,12 @@ Click the type names for complete docs.
|
|
|
188
190
|
|
|
189
191
|
*If we decline a type addition, we will make sure to document the better solution here.*
|
|
190
192
|
|
|
191
|
-
- [`Diff` and `Spread`](https://github.com/sindresorhus/type-fest/pull/7) - The
|
|
193
|
+
- [`Diff` and `Spread`](https://github.com/sindresorhus/type-fest/pull/7) - The pull request author didn't provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider.
|
|
192
194
|
- [`Dictionary`](https://github.com/sindresorhus/type-fest/issues/33) - You only save a few characters (`Dictionary<number>` vs `Record<string, number>`) from [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type), which is more flexible and well-known. Also, you shouldn't use an object as a dictionary. We have `Map` in JavaScript now.
|
|
193
195
|
- [`ExtractProperties` and `ExtractMethods`](https://github.com/sindresorhus/type-fest/pull/4) - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies.
|
|
194
196
|
- [`Url2Json`](https://github.com/sindresorhus/type-fest/pull/262) - Inferring search parameters from a URL string is a cute idea, but not very useful in practice, since search parameters are usually dynamic and defined separately.
|
|
195
|
-
- [`Nullish`](https://github.com/sindresorhus/type-fest/pull/318) - The type only saves a couple of characters, not everyone knows what
|
|
197
|
+
- [`Nullish`](https://github.com/sindresorhus/type-fest/pull/318) - The type only saves a couple of characters, not everyone knows what "nullish" means, and I'm also trying to [get away from `null`](https://github.com/sindresorhus/meta/discussions/7).
|
|
198
|
+
- [`TitleCase`](https://github.com/sindresorhus/type-fest/pull/303) - It's not solving a common need and is a better fit for a separate package.
|
|
196
199
|
|
|
197
200
|
## Alternative type names
|
|
198
201
|
|
|
@@ -607,7 +610,7 @@ There are many advanced types most users don't know about.
|
|
|
607
610
|
```
|
|
608
611
|
</details>
|
|
609
612
|
|
|
610
|
-
- [`ReturnType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype)
|
|
613
|
+
- [`ReturnType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype) - Obtain the return type of a function type.
|
|
611
614
|
<details>
|
|
612
615
|
<summary>
|
|
613
616
|
Example
|
|
@@ -642,7 +645,7 @@ There are many advanced types most users don't know about.
|
|
|
642
645
|
```
|
|
643
646
|
</details>
|
|
644
647
|
|
|
645
|
-
- [`InstanceType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype)
|
|
648
|
+
- [`InstanceType<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype) - Obtain the instance type of a constructor function type.
|
|
646
649
|
<details>
|
|
647
650
|
<summary>
|
|
648
651
|
Example
|
|
@@ -695,7 +698,7 @@ There are many advanced types most users don't know about.
|
|
|
695
698
|
```
|
|
696
699
|
</details>
|
|
697
700
|
|
|
698
|
-
- [`Omit<T, K>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)
|
|
701
|
+
- [`Omit<T, K>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) - Constructs a type by picking all properties from T and then removing K.
|
|
699
702
|
<details>
|
|
700
703
|
<summary>
|
|
701
704
|
Example
|
|
@@ -45,7 +45,7 @@ const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
|
|
|
45
45
|
export type DelimiterCasedPropertiesDeep<
|
|
46
46
|
Value,
|
|
47
47
|
Delimiter extends string,
|
|
48
|
-
> = Value extends Function
|
|
48
|
+
> = Value extends Function | Date | RegExp
|
|
49
49
|
? Value
|
|
50
50
|
: Value extends Array<infer U>
|
|
51
51
|
? Array<DelimiterCasedPropertiesDeep<U, Delimiter>>
|
package/source/get.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {StringDigit} from '../source/utilities';
|
|
2
2
|
import {Split} from './split';
|
|
3
|
+
import {StringKeyOf} from './string-key-of';
|
|
3
4
|
|
|
4
5
|
type GetOptions = {
|
|
5
6
|
strict?: boolean;
|
|
@@ -97,7 +98,7 @@ type WithStringsKeys = keyof WithStrings;
|
|
|
97
98
|
```
|
|
98
99
|
*/
|
|
99
100
|
type WithStringKeys<BaseType extends Record<string | number, any>> = {
|
|
100
|
-
[Key in
|
|
101
|
+
[Key in StringKeyOf<BaseType>]: BaseType[Key]
|
|
101
102
|
};
|
|
102
103
|
|
|
103
104
|
/**
|
|
@@ -138,7 +139,7 @@ Use-case: Retrieve a property from deep inside an API response or some other com
|
|
|
138
139
|
import {Get} from 'type-fest';
|
|
139
140
|
import * as lodash from 'lodash';
|
|
140
141
|
|
|
141
|
-
const get = <BaseType, Path extends string>(object: BaseType, path: Path): Get<BaseType, Path> =>
|
|
142
|
+
const get = <BaseType, Path extends string | string[]>(object: BaseType, path: Path): Get<BaseType, Path> =>
|
|
142
143
|
lodash.get(object, path);
|
|
143
144
|
|
|
144
145
|
interface ApiResponse {
|
|
@@ -160,6 +161,11 @@ const getName = (apiResponse: ApiResponse) =>
|
|
|
160
161
|
get(apiResponse, 'hits.hits[0]._source.name');
|
|
161
162
|
//=> Array<{given: string[]; family: string}>
|
|
162
163
|
|
|
164
|
+
// Path also supports an array of strings
|
|
165
|
+
const getNameWithPathArray = (apiResponse: ApiResponse) =>
|
|
166
|
+
get(apiResponse, ['hits','hits', '0', '_source', 'name']);
|
|
167
|
+
//=> Array<{given: string[]; family: string}>
|
|
168
|
+
|
|
163
169
|
// Strict mode:
|
|
164
170
|
Get<string[], '3', {strict: true}> //=> string | undefined
|
|
165
171
|
Get<Record<string, string>, 'foo', {strict: true}> // => string | undefined
|
|
@@ -169,5 +175,5 @@ Get<Record<string, string>, 'foo', {strict: true}> // => string | undefined
|
|
|
169
175
|
@category Array
|
|
170
176
|
@category Template literal
|
|
171
177
|
*/
|
|
172
|
-
export type Get<BaseType, Path extends string, Options extends GetOptions = {}> =
|
|
173
|
-
GetWithPath<BaseType, ToPath<Path
|
|
178
|
+
export type Get<BaseType, Path extends string | string[], Options extends GetOptions = {}> =
|
|
179
|
+
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
package/source/internal.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Primitive} from './primitive';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
Returns a boolean for whether the two given types are equal.
|
|
3
5
|
|
|
@@ -35,3 +37,8 @@ the inferred tuple `U` and a tuple of length `B`, then extracts the length of tu
|
|
|
35
37
|
export type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...(infer U), ...BuildTuple<B>]
|
|
36
38
|
? TupleLength<U>
|
|
37
39
|
: never;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
Matches any primitive, `Date`, or `RegExp` value.
|
|
43
|
+
*/
|
|
44
|
+
export type BuiltIns = Primitive | Date | RegExp;
|
package/source/partial-deep.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {BuiltIns} from './internal';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
Create a type from another type with all keys and nested keys set to optional.
|
|
@@ -33,8 +33,8 @@ settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
|
|
33
33
|
@category Set
|
|
34
34
|
@category Map
|
|
35
35
|
*/
|
|
36
|
-
export type PartialDeep<T> = T extends
|
|
37
|
-
?
|
|
36
|
+
export type PartialDeep<T> = T extends BuiltIns
|
|
37
|
+
? T
|
|
38
38
|
: T extends Map<infer KeyType, infer ValueType>
|
|
39
39
|
? PartialMapDeep<KeyType, ValueType>
|
|
40
40
|
: T extends Set<infer ItemType>
|
|
@@ -42,7 +42,7 @@ const result: PascalCasedPropertiesDeep<UserWithFriends> = {
|
|
|
42
42
|
@category Template literal
|
|
43
43
|
@category Object
|
|
44
44
|
*/
|
|
45
|
-
export type PascalCasedPropertiesDeep<Value> = Value extends Function
|
|
45
|
+
export type PascalCasedPropertiesDeep<Value> = Value extends Function | Date | RegExp
|
|
46
46
|
? Value
|
|
47
47
|
: Value extends Array<infer U>
|
|
48
48
|
? Array<PascalCasedPropertiesDeep<U>>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {BuiltIns} from './internal';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively.
|
|
@@ -34,7 +34,7 @@ data.foo.push('bar');
|
|
|
34
34
|
@category Set
|
|
35
35
|
@category Map
|
|
36
36
|
*/
|
|
37
|
-
export type ReadonlyDeep<T> = T extends
|
|
37
|
+
export type ReadonlyDeep<T> = T extends BuiltIns | ((...arguments: any[]) => unknown)
|
|
38
38
|
? T
|
|
39
39
|
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
40
40
|
? ReadonlyMapDeep<KeyType, ValueType>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Remove any index signatures from the given object type, so that only explicitly defined properties remain.
|
|
3
|
+
|
|
4
|
+
Use-cases:
|
|
5
|
+
- Remove overly permissive signatures from third-party types.
|
|
6
|
+
|
|
7
|
+
This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
|
|
8
|
+
|
|
9
|
+
It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`.
|
|
10
|
+
|
|
11
|
+
(The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
const indexed: Record<string, unknown> = {}; // Allowed
|
|
15
|
+
|
|
16
|
+
const keyed: Record<'foo', unknown> = {}; // Error
|
|
17
|
+
// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
type Indexed = {} extends Record<string, unknown>
|
|
24
|
+
? '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
25
|
+
: '❌ `{}` is NOT assignable to `Record<string, unknown>`';
|
|
26
|
+
// => '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
27
|
+
|
|
28
|
+
type Keyed = {} extends Record<'foo' | 'bar', unknown>
|
|
29
|
+
? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
|
|
30
|
+
: "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
|
|
31
|
+
// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
38
|
+
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
39
|
+
]: ObjectType[KeyType]; // ...to its original value, i.e. `RemoveIndexSignature<Foo> == Foo`.
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
47
|
+
[KeyType in keyof ObjectType
|
|
48
|
+
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
49
|
+
as {} extends Record<KeyType, unknown>
|
|
50
|
+
? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
|
|
51
|
+
: ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
|
|
52
|
+
]: ObjectType[KeyType];
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
60
|
+
[KeyType in keyof ObjectType
|
|
61
|
+
as {} extends Record<KeyType, unknown>
|
|
62
|
+
? never // => Remove this `KeyType`.
|
|
63
|
+
: KeyType // => Keep this `KeyType` as it is.
|
|
64
|
+
]: ObjectType[KeyType];
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
@example
|
|
69
|
+
```
|
|
70
|
+
import {RemoveIndexSignature} from 'type-fest';
|
|
71
|
+
|
|
72
|
+
interface Example {
|
|
73
|
+
// These index signatures will be removed.
|
|
74
|
+
[x: string]: any
|
|
75
|
+
[x: number]: any
|
|
76
|
+
[x: symbol]: any
|
|
77
|
+
[x: `head-${string}`]: string
|
|
78
|
+
[x: `${string}-tail`]: string
|
|
79
|
+
[x: `head-${string}-tail`]: string
|
|
80
|
+
[x: `${bigint}`]: string
|
|
81
|
+
[x: `embedded-${number}`]: string
|
|
82
|
+
|
|
83
|
+
// These explicitly defined keys will remain.
|
|
84
|
+
foo: 'bar';
|
|
85
|
+
qux?: 'baz';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type ExampleWithoutIndexSignatures = RemoveIndexSignature<Example>;
|
|
89
|
+
// => { foo: 'bar'; qux?: 'baz' | undefined; }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
@category Object
|
|
93
|
+
*/
|
|
94
|
+
export type RemoveIndexSignature<ObjectType> = {
|
|
95
|
+
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
96
|
+
? never
|
|
97
|
+
: KeyType]: ObjectType[KeyType];
|
|
98
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Get keys of the given type as strings.
|
|
3
|
+
|
|
4
|
+
Number keys are converted to strings.
|
|
5
|
+
|
|
6
|
+
Use-cases:
|
|
7
|
+
- Get string keys from a type which may have number keys.
|
|
8
|
+
- Makes it possible to index using strings retrieved from template types.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
import {StringKeyOf} from 'type-fest';
|
|
13
|
+
|
|
14
|
+
type Foo = {
|
|
15
|
+
1: number,
|
|
16
|
+
stringKey: string,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type StringKeysOfFoo = StringKeyOf<Foo>;
|
|
20
|
+
//=> '1' | 'stringKey'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
@category Object
|
|
24
|
+
*/
|
|
25
|
+
export type StringKeyOf<BaseType> = `${Extract<keyof BaseType, string | number>}`;
|