-
-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathindex.test-d.ts
More file actions
84 lines (69 loc) · 3.15 KB
/
index.test-d.ts
File metadata and controls
84 lines (69 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import {expectType, expectAssignable} from 'tsd';
import mapObject, {type Options, mapObjectSkip} from './index.js';
const options: Options = {};
const newObject = mapObject({foo: 'bar'}, (key, value) => [value, key]);
expectAssignable<Record<string | symbol, 'foo'>>(newObject);
expectType<'foo'>(newObject.bar);
const object = mapObject({foo: 'bar'}, (key, value) => [value, key], {
target: {baz: 'baz'},
});
expectAssignable<{baz: string} & Record<string | symbol, 'foo'>>(object);
expectType<'foo'>(object.bar);
expectType<string>(object.baz);
const object1 = mapObject({foo: 'bar'}, (key, value) => [value, key], {
target: {baz: 'baz'},
deep: false,
});
expectAssignable<{baz: string} & Record<string | symbol, 'foo'>>(object1);
expectType<'foo'>(object1.bar);
expectType<string>(object1.baz);
const object2 = mapObject({foo: 'bar'}, (key, value) => [String(value), key], {
deep: true,
});
expectAssignable<Record<string | symbol, unknown>>(object2);
// Deep mapper parameters should be widened
mapObject({fooUpper: true, bAr: {bAz: true}}, (key, value, source) => {
expectAssignable<string>(key); // Without includeSymbols, only string keys
// In deep mode, source is the original input object
expectType<{fooUpper: boolean; bAr: {bAz: boolean}}>(source);
return [String(key), value];
}, {deep: true});
// Shallow mode: source should be the original input type
mapObject({alpha: 1, beta: 2}, (key, value, source) => {
expectType<{alpha: number; beta: number}>(source);
return [key, value];
});
const object3 = mapObject({foo: 'bar'}, (key, value) => [String(value), key], {
deep: true,
target: {bar: 'baz' as const},
});
expectAssignable<Record<string | symbol, unknown>>(object3);
expectType<'baz'>(object3.bar);
mapObject({foo: 'bar'}, (key, value) => [value, key, {shouldRecurse: false}]);
mapObject({foo: 'bar'}, () => mapObjectSkip);
// IncludeSymbols option is available
const optionsWithSymbols: Options = {includeSymbols: true};
// Test symbol key support
const symbolKey = Symbol('test');
const inputWithSymbol = {foo: 'bar', [symbolKey]: 'value'};
// Test that symbol keys work
const resultWithSymbols = mapObject(inputWithSymbol, (key, value) => {
expectAssignable<string | symbol>(key); // With includeSymbols, both string and symbol
return [key, value];
}, {includeSymbols: true});
expectAssignable<Record<string | symbol, string>>(resultWithSymbols);
// Test normal usage
const resultWithoutSymbols = mapObject(inputWithSymbol, (key, value) => {
expectAssignable<string>(key); // Without includeSymbols, only string
return [key, value];
});
expectAssignable<Record<string | symbol, string>>(resultWithoutSymbols);
// Test deep mode with includeSymbols
mapObject({fooUpper: true, [Symbol('test')]: 'symbol'}, (key, value, source) => {
expectAssignable<string | symbol>(key); // With includeSymbols in deep mode
return [String(key), value];
}, {deep: true, includeSymbols: true});
// Verify that without includeSymbols, key type excludes symbols
mapObject({str: 'value'}, (key: string, value) => [key, value]);
// Verify that with includeSymbols, key can be symbol
mapObject({str: 'value'}, (key: string | symbol, value) => [String(key), value], {includeSymbols: true});