-
Notifications
You must be signed in to change notification settings - Fork 86
Open
Description
no matter v1 or v2, the payload types defined don't allow for custom fields. it forces us to cast as any
to be able to use it, making the value of typescript void. custom fields are a huge part of pipedrive so it's really inconvenient that we can't use them properly.
In hope for a faster path of remediation, I've doodled some type utilities which may achieve custom fields at quite low cost. Here below with comments:
// From https://skalt.github.io/projects/brzozowski_ts/
type HexChar = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f";
type IsHex<Str extends string> =
Str extends ""
? true
: Str extends `${HexChar}${infer Rest}`
? IsHex<Rest>
: never;
// From https://stackoverflow.com/a/73369825
type StringLength<Str extends string, Acc extends 0[] = []> =
Str extends `${string}${infer $Rest}`
? StringLength<$Rest, [...Acc, 0]>
: Acc["length"];
type IsLength<S extends string, Length extends number> = StringLength<S> extends Length ? true : false
// A custom field id is 40 char hex string
type CustomFieldId<T extends string> =
IsHex<T> extends true
? IsLength<T, 40> extends true
? string
: never
: never
type WithCustomFields<T, BaseType> = {
[Key in keyof T]:
Key extends string
? Key extends keyof T
? Value[Key]
: CustomFieldId<Key>
: never
}
// --- Example implementation
export type AddOrganizationRequest = {
'name'?: string;
'owner_id'?: number;
'add_time'?: string;
'update_time'?: string;
}
// We let arg be broader than AddOrganizationRequest by defining it as extends and pass the basic blueprint as K. This allow to compare and keep types of BaseType untouched and iterate on T and allow extension if some keyof T are CustomFieldId
function test<T extends BaseType, BaseType = AddOrganizationRequest>(arg: WithCustomFields<T, BaseType>) {}
test({
name: 'foo',
owner_id: 0,
add_time: 'foo',
update_time: 'foo',
['deadbeefdeadbeefdeadbeefdeadbeefdeadbeef']: 'foo', // allowed
})
test({
name: 'foo',
owner_id: 0,
add_time: 'foo',
update_time: 'foo',
['qwe']: 'foo', // denied
['deadbeefdeadbeefdeadbeefdeadbeefdeadbeef']: 'foo', // allowed
})
test({
name: 'foo',
owner_id: 0,
add_time: 'foo',
update_time: 'foo',
['qwe']: 'foo', // denied
})
jvoristaskworld
Metadata
Metadata
Assignees
Labels
No labels