From ba00d9a41564332d2afd3cd9b06cc2928d1e4104 Mon Sep 17 00:00:00 2001
From: Paul Visscher
Date: Mon, 8 Apr 2024 14:15:58 +0200
Subject: [PATCH] refactor(values-of): more consistent type inference
---
src/object/values-of/values-of.spec.ts | 14 +++++++++-----
src/object/values-of/values-of.ts | 6 ++----
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/object/values-of/values-of.spec.ts b/src/object/values-of/values-of.spec.ts
index 090701b..4ba64f4 100644
--- a/src/object/values-of/values-of.spec.ts
+++ b/src/object/values-of/values-of.spec.ts
@@ -2,7 +2,7 @@ import { valuesOf } from './index.js'
import { forAll, record, unknown, string, array, oneOf, integer } from '../../random/index.js'
-import { expect, it } from 'vitest'
+import { expect, it, expectTypeOf } from 'vitest'
it('valuesOf === Object.values', () => {
forAll(record(unknown()), (o) => {
@@ -30,8 +30,12 @@ it('valuesOf union object and array', () => {
forAll(oneOf(array(string()), record([integer(), integer()])), (o) => {
expect(valuesOf(o)).toStrictEqual(Object.values(o))
})
- const _foo: number[] = valuesOf([1, 2, 3])
- const _foo2: (number | string)[] = valuesOf([1, '2', 3])
- const _foo3: 'bar'[] = valuesOf({ foo: 'bar' } as const)
- const _foo4: number[] | string[] = valuesOf({ foo: 'bar' })
+})
+
+it('types', () => {
+ expectTypeOf(valuesOf({ foo: 'bar' })).toEqualTypeOf<'bar'[]>()
+ expectTypeOf(valuesOf({ foo: 'bar' })).toEqualTypeOf()
+
+ expectTypeOf(valuesOf([1, 2, 3])).toEqualTypeOf<(1 | 2 | 3)[]>()
+ expectTypeOf(valuesOf([1, '2', 3])).toEqualTypeOf<(1 | '2' | 3)[]>()
})
diff --git a/src/object/values-of/values-of.ts b/src/object/values-of/values-of.ts
index 9e02666..bc8a462 100644
--- a/src/object/values-of/values-of.ts
+++ b/src/object/values-of/values-of.ts
@@ -1,6 +1,4 @@
-import type { KeyOf } from '../../type/index.js'
-
-export type ValuesOf = T extends (infer I)[] ? I[] : T[KeyOf][]
+export type ValuesOf | {}> = T extends readonly (infer I)[] ? I[] : T[keyof T][]
/**
* Returns an array of values of the enumerable properties of an object.
@@ -23,6 +21,6 @@ export type ValuesOf = T extends (infer I)[] ? I[] : T[KeyOf][]
*
* @group Object
*/
-export function valuesOf | {}>(obj: T): ValuesOf {
+export function valuesOf | {}>(obj: T): ValuesOf {
return Object.values(obj) as ValuesOf
}