Skip to content

Commit

Permalink
Add CamelCasedProps, CamelCasedPropsDeep etc. types (#179)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
wwwzbwcom and sindresorhus committed Mar 22, 2021
1 parent 2f6aa0b commit c043c25
Show file tree
Hide file tree
Showing 28 changed files with 687 additions and 13 deletions.
10 changes: 10 additions & 0 deletions readme.md
Expand Up @@ -111,10 +111,20 @@ Click the type names for complete docs.
*Note:* These require [TypeScript 4.1 or newer](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#template-literal-types).

- [`CamelCase`](ts41/camel-case.d.ts) – Convert a string literal to camel-case (`fooBar`).
- [`CamelCasedProperties`](ts41/camel-cased-properties.d.ts) – Convert object properties to camel-case (`fooBar`).
- [`CamelCasedPropertiesDeep`](ts41/camel-cased-properties-deep.d.ts) – Convert object properties to camel-case recursively (`fooBar`).
- [`KebabCase`](ts41/kebab-case.d.ts) – Convert a string literal to kebab-case (`foo-bar`).
- [`KebabCasedProperties`](ts41/kebab-cased-properties.d.ts) – Convert a object properties to kebab-case recursively (`foo-bar`).
- [`KebabCasedPropertiesDeep`](ts41/kebab-cased-properties-deep.d.ts) – Convert object properties to kebab-case (`foo-bar`).
- [`PascalCase`](ts41/pascal-case.d.ts) – Converts a string literal to pascal-case (`FooBar`)
- [`PascalCasedProperties`](ts41/pascal-cased-properties.d.ts) – Converts object properties to pascal-case (`FooBar`)
- [`PascalCasedPropertiesDeep`](ts41/pascal-cased-properties-deep.d.ts) – Converts object properties to pascal-case (`FooBar`)
- [`SnakeCase`](ts41/snake-case.d.ts) – Convert a string literal to snake-case (`foo_bar`).
- [`SnakeCasedProperties`](ts41/snake-cased-properties-deep.d.ts) – Convert object properties to snake-case (`foo_bar`).
- [`SnakeCasedPropertiesDeep`](ts41/snake-cased-properties-deep.d.ts) – Convert object properties to snake-case recursively (`foo_bar`).
- [`DelimiterCase`](ts41/delimiter-case.d.ts) – Convert a string literal to a custom string delimiter casing.
- [`DelimiterCasedProperties`](ts41/delimiter-cased-properties.d.ts) – Convert object properties to a custom string delimiter casing.
- [`DelimiterCasedPropertiesDeep`](ts41/delimiter-cased-properties-deep.d.ts) – Convert object properties to a custom string delimiter casing recursively.
- [`Split`](ts41/split.d.ts) - Represents an array of strings split using a given character or character set.
- [`Trim`](ts41/trim.d.ts) - Remove leading and trailing spaces from a string.
- [`Get`](ts41/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.
Expand Down
4 changes: 2 additions & 2 deletions test-d/camel-case.ts
Expand Up @@ -38,7 +38,7 @@ const camelFromRepeatedSeparators: CamelCase<'foo____bar'> = 'fooBar';
expectType<'fooBar'>(camelFromRepeatedSeparators);

// Verifying example
type CamelCasedProps<T> = {
type CamelCasedProperties<T> = {
[K in keyof T as CamelCase<K>]: T[K]
};

Expand All @@ -48,7 +48,7 @@ interface RawOptions {
foo: number;
}

expectAssignable<CamelCasedProps<RawOptions>>({
expectAssignable<CamelCasedProperties<RawOptions>>({
dryRun: true,
fullFamilyName: 'bar.js',
foo: 123
Expand Down
41 changes: 41 additions & 0 deletions test-d/camel-cased-properties-deep.ts
@@ -0,0 +1,41 @@
import {CamelCasedPropertiesDeep} from '../ts41/camel-cased-properties-deep';
import {expectType} from 'tsd';

declare const foo: CamelCasedPropertiesDeep<{A: {B: number; C: Array<{D: string}>}}>;

expectType<{a: {b: number; c: Array<{d: string}>}}>(foo);

declare const fooBar: CamelCasedPropertiesDeep<() => {a: string}>;
expectType<() => {a: string}>(fooBar);

declare const bar: CamelCasedPropertiesDeep<Set<{fooBar: string}>>;
expectType<Set<{fooBar: string}>>(bar);

// Verify example
interface User {
UserId: number;
UserName: string;
}

interface UserWithFriends {
UserInfo: User;
UserFriends: User[];
}

const result: CamelCasedPropertiesDeep<UserWithFriends> = {
userInfo: {
userId: 1,
userName: 'Tom'
},
userFriends: [
{
userId: 2,
userName: 'Jerry'
},
{
userId: 3,
userName: 'Spike'
}
]
};
expectType<CamelCasedPropertiesDeep<UserWithFriends>>(result);
24 changes: 24 additions & 0 deletions test-d/camel-cased-properties.ts
@@ -0,0 +1,24 @@
import {CamelCasedProperties} from '../ts41/camel-cased-properties';
import {expectType} from 'tsd';

declare const foo: CamelCasedProperties<{A: number; B: {C: string}}>;

expectType<{a: number; b: {C: string}}>(foo);

declare const bar: CamelCasedProperties<Array<{helloWorld: string}>>;
expectType<Array<{helloWorld: string}>>(bar);

declare const fooBar: CamelCasedProperties<() => {a: string}>;
expectType<() => {a: string}>(fooBar);

// Verify example
interface User {
UserId: number;
UserName: string;
}

const result: CamelCasedProperties<User> = {
userId: 1,
userName: 'Tom'
};
expectType<CamelCasedProperties<User>>(result);
4 changes: 2 additions & 2 deletions test-d/delimiter-case.ts
Expand Up @@ -44,7 +44,7 @@ const delimiterFromRepeatedSeparators: DelimiterCase<'foo____bar', '#'> = 'foo##
expectType<'foo####bar'>(delimiterFromRepeatedSeparators);

// Verifying example
type OddCasedProps<T> = {
type OddCasedProperties<T> = {
[K in keyof T as DelimiterCase<K, '#'>]: T[K]
};

Expand All @@ -54,7 +54,7 @@ interface CliOptions {
foo: number;
}

expectAssignable<OddCasedProps<CliOptions>>({
expectAssignable<OddCasedProperties<CliOptions>>({
'dry#run': true,
'include#file': 'bar.js',
foo: 123
Expand Down
40 changes: 40 additions & 0 deletions test-d/delimiter-cased-properties-deep.ts
@@ -0,0 +1,40 @@
import {expectType} from 'tsd';
import {DelimiterCasedPropertiesDeep} from '../ts41/delimiter-cased-properties-deep';

declare const foo: DelimiterCasedPropertiesDeep<{helloWorld: {fooBar: string}}, '/'>;
expectType<{'hello/world': {'foo/bar': string}}>(foo);

declare const fooBar: DelimiterCasedPropertiesDeep<() => {a: string}, '/'>;
expectType<() => {a: string}>(fooBar);

declare const bar: DelimiterCasedPropertiesDeep<Set<{fooBar: string}>, '-'>;
expectType<Set<{'foo-bar': string}>>(bar);

// Verify example
interface User {
userId: number;
userName: string;
}

interface UserWithFriends {
userInfo: User;
userFriends: User[];
}

const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
'user-info': {
'user-id': 1,
'user-name': 'Tom'
},
'user-friends': [
{
'user-id': 2,
'user-name': 'Jerry'
},
{
'user-id': 3,
'user-name': 'Spike'
}
]
};
expectType<DelimiterCasedPropertiesDeep<UserWithFriends, '-'>>(result);
22 changes: 22 additions & 0 deletions test-d/delimiter-cased-properties.ts
@@ -0,0 +1,22 @@
import {expectType} from 'tsd';
import {DelimiterCasedProperties} from '../ts41/delimiter-cased-properties';

declare const foo: DelimiterCasedProperties<{helloWorld: {fooBar: string}}, '/'>;
expectType<{'hello/world': {fooBar: string}}>(foo);

declare const bar: DelimiterCasedProperties<Array<{helloWorld: string}>, '-'>;
expectType<Array<{helloWorld: string}>>(bar);

declare const fooBar: DelimiterCasedProperties<() => {a: string}, '-'>;
expectType<() => {a: string}>(fooBar);

// Verify example
interface User {
userId: number;
userName: string;
}
const result: DelimiterCasedProperties<User, '-'> = {
'user-id': 1,
'user-name': 'Tom'
};
expectType<DelimiterCasedProperties<User, '-'>>(result);
37 changes: 37 additions & 0 deletions test-d/kebab-cased-properties-deep.ts
@@ -0,0 +1,37 @@
import {KebabCasedPropertiesDeep} from '../ts41/kebab-cased-properties-deep';
import {expectType} from 'tsd';

declare const foo: KebabCasedPropertiesDeep<{helloWorld: {fooBar: string}}>;
expectType<{'hello-world': {'foo-bar': string}}>(foo);

declare const bar: KebabCasedPropertiesDeep<Set<{fooBar: string}>>;
expectType<Set<{'foo-bar': string}>>(bar);

// Verify example
interface User {
userId: number;
userName: string;
}

interface UserWithFriends {
userInfo: User;
userFriends: User[];
}

const result: KebabCasedPropertiesDeep<UserWithFriends> = {
'user-info': {
'user-id': 1,
'user-name': 'Tom'
},
'user-friends': [
{
'user-id': 2,
'user-name': 'Jerry'
},
{
'user-id': 3,
'user-name': 'Spike'
}
]
};
expectType<KebabCasedPropertiesDeep<UserWithFriends>>(result);
16 changes: 16 additions & 0 deletions test-d/kebab-cased-properties.ts
@@ -0,0 +1,16 @@
import {KebabCasedProperties} from '../ts41/kebab-cased-properties';
import {expectType} from 'tsd';

declare const foo: KebabCasedProperties<{helloWorld: {fooBar: string}}>;
expectType<{'hello-world': {fooBar: string}}>(foo);

// Verify example
interface User {
userId: number;
userName: string;
}
const result: KebabCasedProperties<User> = {
'user-id': 1,
'user-name': 'Tom'
};
expectType<KebabCasedProperties<User>>(result);
40 changes: 40 additions & 0 deletions test-d/pascal-cased-properties-deep.ts
@@ -0,0 +1,40 @@
import {PascalCasedPropertiesDeep} from '../ts41/pascal-cased-properties-deep';
import {expectType} from 'tsd';

declare const foo: PascalCasedPropertiesDeep<{helloWorld: {fooBar: string}}>;
expectType<{HelloWorld: {FooBar: string}}>(foo);

declare const fooBar: PascalCasedPropertiesDeep<() => {a: string}>;
expectType<() => {a: string}>(fooBar);

declare const bar: PascalCasedPropertiesDeep<Set<{fooBar: string}>>;
expectType<Set<{FooBar: string}>>(bar);

// Verify example
interface User {
userId: number;
userName: string;
}

interface UserWithFriends {
userInfo: User;
userFriends: User[];
}

const result: PascalCasedPropertiesDeep<UserWithFriends> = {
UserInfo: {
UserId: 1,
UserName: 'Tom'
},
UserFriends: [
{
UserId: 2,
UserName: 'Jerry'
},
{
UserId: 3,
UserName: 'Spike'
}
]
};
expectType<PascalCasedPropertiesDeep<UserWithFriends>>(result);
22 changes: 22 additions & 0 deletions test-d/pascal-cased-properties.ts
@@ -0,0 +1,22 @@
import {PascalCasedProperties} from '../ts41/pascal-cased-properties';
import {expectType} from 'tsd';

declare const foo: PascalCasedProperties<{helloWorld: {fooBar: string}}>;
expectType<{HelloWorld: {fooBar: string}}>(foo);

declare const bar: PascalCasedProperties<Array<{helloWorld: string}>>;
expectType<Array<{helloWorld: string}>>(bar);

declare const fooBar: PascalCasedProperties<() => {a: string}>;
expectType<() => {a: string}>(fooBar);

// Verify example
interface User {
userId: number;
userName: string;
}
const result: PascalCasedProperties<User> = {
UserId: 1,
UserName: 'Tom'
};
expectType<PascalCasedProperties<User>>(result);
37 changes: 37 additions & 0 deletions test-d/snake-cased-properties-deep.ts
@@ -0,0 +1,37 @@
import {SnakeCasedPropertiesDeep} from '../ts41/snake-cased-properties-deep';
import {expectType} from 'tsd';

declare const foo: SnakeCasedPropertiesDeep<{helloWorld: {fooBar: string}}>;
expectType<{hello_world: {foo_bar: string}}>(foo);

declare const bar: SnakeCasedPropertiesDeep<Set<{fooBar: string}>>;
expectType<Set<{foo_bar: string}>>(bar);

// Verify example
interface User {
userId: number;
userName: string;
}

interface UserWithFriends {
userInfo: User;
userFriends: User[];
}

const result: SnakeCasedPropertiesDeep<UserWithFriends> = {
user_info: {
user_id: 1,
user_name: 'Tom'
},
user_friends: [
{
user_id: 2,
user_name: 'Jerry'
},
{
user_id: 3,
user_name: 'Spike'
}
]
};
expectType<SnakeCasedPropertiesDeep<UserWithFriends>>(result);
16 changes: 16 additions & 0 deletions test-d/snake-cased-properties.ts
@@ -0,0 +1,16 @@
import {SnakeCasedProperties} from '../ts41/snake-cased-properties';
import {expectType} from 'tsd';

declare const foo: SnakeCasedProperties<{helloWorld: {fooBar: string}}>;
expectType<{hello_world: {fooBar: string}}>(foo);

// Verify example
interface User {
userId: number;
userName: string;
}
const result: SnakeCasedProperties<User> = {
user_id: 1,
user_name: 'Tom'
};
expectType<SnakeCasedProperties<User>>(result);
4 changes: 2 additions & 2 deletions ts41/camel-case.d.ts
Expand Up @@ -44,7 +44,7 @@ const someVariable: CamelCase<'foo-bar'> = 'fooBar';
// Advanced
type CamelCasedProps<T> = {
type CamelCasedProperties<T> = {
[K in keyof T as CamelCase<K>]: T[K]
};
Expand All @@ -54,7 +54,7 @@ interface RawOptions {
foo: number;
}
const dbResult: CamelCasedProps<ModelProps> = {
const dbResult: CamelCasedProperties<ModelProps> = {
dryRun: true,
fullFamilyName: 'bar.js',
foo: 123
Expand Down

0 comments on commit c043c25

Please sign in to comment.