-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Useless Partial
in type definition
#147
Comments
I think I'm with you on the two-type case. There are some other cases that I think we should add type tests for before dropping the one-type case, or the interface Whatever {
important: string,
info: string,
}
const merged = deepmerge<Whatever>(
{ important: 'yes' },
{ info: 'okay' }
)
const alsoMerged = deepmerge.all<Whatever>([
{ important: 'yes' },
{ info: 'okay' },
{ info: 'really?' }
]) I haven't been doing a lot of TS lately, so let me know if you think there's a more idiomatic way to type those operations |
@TehShrike In the first case, you don't have to specify the template type. → Playground code declare function deepmerge<T1, T2>(x:T1, y: T2): T1 & T2;
interface Whatever {
important: string,
info: string,
}
// The inferred type is `{important: string} & {info: string}`,
// which is equivalent to `Whatever`.
const merged = deepmerge(
{ important: 'yes' },
{ info: 'okay' }
)
// Also you specify `Whatever` type explicitly. No errors.
const merged2: Whatever = deepmerge(
{ important: 'yes' },
{ info: 'okay' }
) The second case is more complicated. TypeScript does not have a perfect solution for functions like See official typings of I think declare function deepmerge<T1, T2>(x:T1, y: T2): T1 & T2;
declare namespace deepmerge {
export function all<T1, T2> (objects: [T1, T2]): T1 & T2;
export function all<T1, T2, T3> (objects: [T1, T2, T3]): T1 & T2 & T3;
export function all<T1, T2, T3, T4> (objects: [T1, T2, T3, T4]): T1 & T2 & T3 & T4;
export function all<T1, T2, T3, T4, T5> (objects: [T1, T2, T3, T4, T5]): T1 & T2 & T3 & T4 & T5;
export function all<T> (objects: T[]): T;
}
interface Whatever {
important: string,
info: string,
}
// The inferred type: `{important: string} & {info: string} & {info: string}`,
// which is equivalent to `Whatever`
const merged = deepmerge.all([
{ important: 'yes' },
{ info: 'okay' },
{ info: 'really?' }
])
// It's same to the result of official `Object.assign` typing.
const merged2 = Object.assign(
{ important: 'yes' },
{ info: 'okay' },
{ info: 'really?' }
);
// # More than 5 params
// The inferred type: `{important: string, info?: string} | {important?: string, info: string}`,
// which is NOT equivalent to `Whatever`.
const merged3 = deepmerge.all([
{ important: 'yes' },
{ info: 'okay' },
{ info: 'okay1' },
{ info: 'okay2' },
{ info: 'okay3' },
{ info: 'really?' }
]);
// So just cast, honestly.
// Because tsc can not guarantee that the typing is correct statically.
const merged4 = deepmerge.all([
{ important: 'yes' },
{ info: 'okay' },
{ info: 'okay1' },
{ info: 'okay2' },
{ info: 'okay3' },
{ info: 'really?' }
]) as Whatever; Casting is better than using If you like this idea, I will update my PR. |
With your first example, explicitly declaring a generic type will fix the issue. E.g. const result = merge<T>(t1, t2); I don't think the issue is with |
I think I agree with you that |
@RebeccaStevens const result = deepmerge<{a: string}>({}, {});
console.log(result.a.toUpperCase()); // throw a runtime error
Yes, so you don't have to specify declare function deepmerge<T1, T2>(x:T1, y: T2, options?: deepmerge.Options): T1 & T2; Imagine re-implementing this |
@teppeis What's your thoughts on this alternative type def? declare function deepmerge<T0 extends T1 & T2, T1, T2>(x: T1, y: T2, options?: deepmerge.Options): T0; |
@RebeccaStevens The same error occurs as in the first example. |
Isn't the |
What I really want is being able to use |
@s-edlund Can you give a code example? |
Sure:
Gives error:
|
So with the current implementation of this library's types, In the new proposed implementation, that error message is desired as based on the types of the inputs, the resulting type is |
I don't know why
Partial<>
is used for the types of params.The
Partial<>
causes a difference between static typing and actual values in runtime.I think the
Partial<>
should be just removed.The text was updated successfully, but these errors were encountered: