Skip to content

Commit

Permalink
fix the return type of typedHasProperty yet again
Browse files Browse the repository at this point in the history
  • Loading branch information
electrovir committed Oct 12, 2022
1 parent 8c8791e commit 398cf05
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 13 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "augment-vir",
"version": "3.0.1",
"version": "3.0.2",
"homepage": "https://github.com/electrovir/augment-vir",
"bugs": {
"url": "https://github.com/electrovir/augment-vir/issues"
Expand Down
37 changes: 36 additions & 1 deletion src/augments/object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,17 @@ describe(typedHasProperty.name, () => {
const idkWhatThisIs: unknown = (() => {}) as unknown;
if (typedHasProperty(idkWhatThisIs, 'name')) {
idkWhatThisIs.name;
if (typedHasProperty(idkWhatThisIs, 'derp')) {
idkWhatThisIs.derp;
}
} else {
// @ts-expect-error
idkWhatThisIs.name;
}
});

it('should preserve property value type when it exists', () => {
const whatever = {} as {name: string} | string;
const whatever = {} as {name: string} | string | {derp: string};

// should not be able to access the property directly
// @ts-expect-error
Expand Down Expand Up @@ -300,6 +303,38 @@ describe(typedHasProperty.name, () => {
}
}
});

it('should allow type narrowing', () => {
function assertOutputProperty(
keyPath: string,
testExpectations: object,
outputKey: string,
): void {
if (!typedHasProperty(testExpectations, outputKey)) {
throw new Error(`${keyPath} > ${outputKey} is missing.`);
}

const value = testExpectations[outputKey];

if (typeof value !== 'string' && !isObject(value)) {
throw new Error(`${keyPath} > "${outputKey}" is invalid. Got "${value}"`);
} else if (isObject(value)) {
if (!typedHasProperty(value, 'type') || value.type !== 'regexp') {
throw new Error(
`${keyPath} > "${outputKey}".type is invalid. Expected "regexp".`,
);
}

value;

if (!typedHasProperty(value, 'value') || typeof value.value !== 'string') {
throw new Error(
`${keyPath} > "${outputKey}".value is invalid. Expected a string.`,
);
}
}
}
});
});

describe(typedHasProperties.name, () => {
Expand Down
18 changes: 9 additions & 9 deletions src/augments/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ export function getObjectTypedValues<ObjectGeneric extends unknown>(
) as ObjectGeneric[keyof ObjectGeneric][];
}

type CombineTypeWithKey<
type CombinedParentValue<
KeyGeneric extends PropertyKey,
ParentGeneric,
> = ParentGeneric extends Partial<Record<KeyGeneric, unknown>>
? ParentGeneric & RequiredBy<ParentGeneric, KeyGeneric>
: ParentGeneric extends
| Record<KeyGeneric, infer ValueGeneric>
| Partial<Record<KeyGeneric, infer ValueGeneric>>
| {}
? Extract<ParentGeneric, RequiredBy<Record<KeyGeneric, ValueGeneric>, KeyGeneric>>
: ParentGeneric & Record<KeyGeneric, unknown>;
> = KeyGeneric extends keyof ParentGeneric
? RequiredBy<ParentGeneric, KeyGeneric>[KeyGeneric]
: KeyGeneric extends keyof Extract<ParentGeneric, Record<KeyGeneric, any>>
? RequiredBy<Extract<ParentGeneric, Record<KeyGeneric, any>>, KeyGeneric>[KeyGeneric]
: unknown;

type CombineTypeWithKey<KeyGeneric extends PropertyKey, ParentGeneric> = ParentGeneric &
RequiredBy<Record<KeyGeneric, CombinedParentValue<KeyGeneric, ParentGeneric>>, KeyGeneric>;

export function typedHasProperty<KeyGeneric extends PropertyKey, ParentGeneric>(
inputObject: ParentGeneric,
Expand Down
12 changes: 12 additions & 0 deletions src/augments/type-test.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {describe, it} from 'mocha';
import {DoesExtend, ExpectFalse, ExpectTrue} from './type-test';

describe('DoesExtend', () => {
it('should work on types', () => {
type one = ExpectTrue<DoesExtend<unknown, Record<PropertyKey, any>>>;
type two = ExpectFalse<DoesExtend<Record<PropertyKey, any>, unknown>>;
// type three = ExpectFalse<DoesExtend<Record<'name', any>, {name: string} | string>>;
type four = ExpectTrue<DoesExtend<{name: string} | string, Record<'name', any>>>;
type five = ExpectTrue<DoesExtend<{name: string} | string, Record<'name', any>>>;
});
});

0 comments on commit 398cf05

Please sign in to comment.