feat: add propperly typed hasOwn util

This commit is contained in:
Jiří Čermák
2025-12-04 09:20:53 +01:00
committed by Jiří Čermák
parent f9ed4920c0
commit 972d021017
2 changed files with 36 additions and 0 deletions

View File

@@ -11,3 +11,20 @@ export type GetObjectWithoutKey<U, K extends PropertyKey> = U extends object
: never;
export type ObjectsOnly<T> = T extends Record<string, unknown> ? T : never;
/**
* All keys of types in a union.
*
* Example:
* ```
* type T = { a: number; b: string } & ({ foo: numer } | { bar: string });
* type K: KeysOfUnion<T>; // 'a' | 'b' | 'foo' | 'bar'
* ```
*/
export type KeysOfUnion<T> = T extends T ? keyof T : never;
export type NarrowObjectWithKey<T, K extends PropertyKey> = T extends any
? K extends keyof T
? T
: never
: never;

View File

@@ -1,3 +1,5 @@
import { KeysOfUnion, NarrowObjectWithKey } from '@trezor/type-utils';
export const typedObjectEntries = <T extends Record<string, unknown>>(
obj: T,
): [keyof T, T[keyof T]][] => Object.entries(obj) as [keyof T, T[keyof T]][];
@@ -13,3 +15,20 @@ export const typedObjectKeys = <T extends Record<any, any>>(obj: T): Array<keyof
export const typedObjectValues = <T extends Record<any, any>>(obj: T): Array<T[keyof T]> =>
Object.values(obj) as Array<T[keyof T]>;
/**
* @example
* ```ts
* type Props = { a: number; b: string } & ({ foo: number } | { bar: string });
*
* function someFn(props: Props) {
* return hasOwn(props, 'foo') ? props.foo : props.bar;
* }
* ```
*/
export function hasOwn<T extends object, K extends KeysOfUnion<T>>(
obj: T,
key: K,
): obj is NarrowObjectWithKey<T, K> {
return Object.hasOwn(obj, key);
}