question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Partial type for reduce initialValue

See original GitHub issue

Search Terms

reduce initialvalue partial type assertion

Suggestion

Add a signature to the type for Array.reduce<U> to allow the initialValue to be a Partial<U>

Use Cases

Many cases where the reduce function is used to build an object that will eventually conform to U, but starts with an empty accumulator.

Examples

Simple example where the initialValue does not satisfy U but the final result will:

['one'].reduce<{ one: string }>((acc, i) => ({ [i]: i, ...acc }), {})

This yields

Argument of type ‘{}’ is not assignable to parameter of type ‘{ one: string; }’. Property ‘one’ is missing in type ‘{}’ but required in type ‘{ one: string; }’.

Calling the function without an initialValue causes problems because the initialValue needs to be an object for this to work.

The below type signature would fix this issue:

interface Array<T> {
  reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: Partial<U>): U;
}

Checklist

My suggestion meets these guidelines:

  • [?] This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:6
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
bsandercommented, Dec 11, 2018

Narratively I still think that allowing for a Partial makes sense here as the whole point of a reduce operation is to accumulate a single value from a list. Also, the type assertions are exactly the thing I’m trying to avoid.

How about at least allowing the opportunity to type the initialValue separately, while defaulting to U:

interface Array<T> {
  reduce<U, V = U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: V): U;
}

Or add it as an overload without the default for V. It could also be made more narrow by doing reduce<U extends V, V = U>.

3reactions
AnyhowStepcommented, Dec 7, 2018

If anything, you should make your code,

declare function isU (partialU : Partial<U>) : partialU is U;

function doSomething (someArr : T[]) : U {
    const partialResult : Partial<U> = someArr.reduce<Partial<U>>(
        (memo, item) => {
            memo[item.someField] = transform(item);
            return memo;
        },
        {} /*Assuming your Partial<U> allows the empty object*/
    );

    if (isU(partialU)) {
        return partialU;
    } else {
        throw new Error(`Failed to build U`);
    }
}

If you’re going to say “Oh, I know that it will build U for sure!”

function doSomething (someArr : T[]) : U {
    const partialResult : Partial<U> = someArr.reduce<Partial<U>>(
        (memo, item) => {
            memo[item.someField] = transform(item);
            return memo;
        },
        {} /*Assuming your Partial<U> allows the empty object*/
    );

    return partialU as U;
}

In my opinion, we do not need to make Array.reduce<>() less type-safe just for this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Partial type for reduce initialValue · Issue #28901 - GitHub
Many cases where the reduce function is used to build an object that will eventually conform to U , but starts with an...
Read more >
When using Array.reduce() and the initial value is an empty ...
Given an interface with non-optional keys and an empty initial value, you need to type the reducer as Partial<T> , but by the...
Read more >
TypeScript how to set types for accumulated Value and ...
I just want to know why I cannot set a type to my accumulator as a number. and how should I set types...
Read more >
TypeScript: adjusting types in reduce function with an async ...
In TypeScript, I was using the Array.prototype.reduce() method to iterate on an array and populate an object based on an asynchronous ...
Read more >
reduce(_:_:) | Apple Developer Documentation
A closure that combines an accumulating value and an element of the sequence into a new accumulating value, to be used in the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found