type-fest
type-fest copied to clipboard
Cannot copy Date type via CamelCasedPropertiesDeep
I'm currently using CamelCasedPropertiesDeep
type and I found that it's not copy Date type, instead it creates copy of it. I've got this error
Argument of type '{ toString: () => string; toDateString
string; toLocaleString: { (): string; (locales?: string | string[] | undefined, options?: DateTimeFormatOptions | undefineON: (key?: any) => string; }' is not assignable to parameter of type 'number | Date'.
So I tried it with another standard build-in object types and it works with none of them.
interface ExampleType {
bool: Boolean
sym: Symbol
error: Error
num: Number
bigInt: BigInt
math: Math
date: Date
str: String
regExp: RegExp
array: Int8Array
map: Map<any,any>
weakMap: WeakMap<any, any>
weakSet: WeakSet<any>
json: JSON
promise: Promise<any>
generator: Generator
dateTimeFormat: Intl.DateTimeFormat
}
type CamelizedExample = CamelCasedPropertiesDeep<ExampleType>
Here you can try to camelize keys of an object I've present above and notice this issue.
Upvote & Fund
- We're using Polar.sh so you can upvote and help fund this issue.
- The funding will be given to active contributors.
- Thank you in advance for helping prioritize & fund our backlog.
I think easiest solution here would be to add a new exclude
parameter like CamelCasedPropertiesDeep<ExampleType, String | Date>
Some of these should be getting built in support though, like Promise
, Map
and maybe Date
.
@voxpelli I'm thinking about add check like
: Value extends Map<infer Key, infer Val>
? Map<CamelCasedPropertiesDeep<Key>, Val>
: Value extends StandartBuildInTypes
? Value
: {
...
}
This will copy type instead of iterating it and creating the new ones. StandartBuildInTypes
is just the union of standart types excluding Object
and iterative types.
What do you think? I've searching for the way to distinguish types like Date
and RegExp
from Object
for the whole day, but I haven't found any good way except I've describe above.
A problem with that way is how TypeScript defines object: That its pure duck typing: As long as it looks like a duck, quacks like a duck, it is a duck.
See eg this playground.
A Value extends Boolean
matches not only Boolean
, but also the NonFake2
and FakeBoolean
in that example:
interface NonFake {
test: 'test'
}
interface NonFake2 {
test: 'test'
valueOf: () => boolean
}
interface FakeBoolean {
valueOf: () => boolean
}
In other words: Any object that implements valueOf: () => boolean
.
Because of that we can't really add these basic ones in my opinion, but we can add the more complex ones which are less likely to cause false positives.
I think easiest solution here would be to add a new
exclude
parameter likeCamelCasedPropertiesDeep<ExampleType, String | Date>
Did you mean create second optional type parameter that will be exceptional to deep copy?
I think easiest solution here would be to add a new
exclude
parameter likeCamelCasedPropertiesDeep<ExampleType, String | Date>
Did you mean create second optional type parameter that will be exceptional to deep copy?
Yes, because then one adds it when one only adds it when one knows it won't create any false matches.
@voxpelli https://github.com/sindresorhus/type-fest/pull/327
It should use the same solution as done here: https://github.com/sdotson/type-fest/blob/da1a717790396afb0fab16dfc61f6d3df5d0b6fb/source/delimiter-cased-properties-deep.d.ts#L48