MichaelAttard
MichaelAttard

Reputation: 2158

Is it possible to enforce parameter to be a key of certain type?

Say we have the following lodash usage:

type Baz = {
    sortOrder: number
}

const baz: Baz;

_.chain(baz)
    .sortBy("sortOrder")
    .value();

Would it be possible to restrict "sortOrder" to be keyof Baz without overriding .sortBy type definitions, or have to extract "sortOrder" to a variable?

Upvotes: 1

Views: 39

Answers (1)

Remo H. Jansen
Remo H. Jansen

Reputation: 24941

Based on your request:

without overriding .sortBy type definitions

Your best option is to wrap the functionality with a function?

function sortBy<T, K extends keyof T>(key: K, arr: T[]) {
    return _.chain(arr)
            .sortBy(key)
            .value();
}

As an extra would be nice to allow the partial application of sortBy. So you can use the functionsortBy to define other functions like sortByAge and sortByName:

const sortBy = <T, K extends keyof T>(key: K) => (arr: T[]) => {
    return _.chain(arr)
            .sortBy(key)
            .value();
}

interface Person {
    name: string;
    age: number;
}

const sortByAge = sortBy<Person, "age">("age");
const sortByName = sortBy<Person, "name">("name");

// Error Type '"namr"' does not satisfy the constraint '"age" | "name"'.
const sortByWrongKey = sortBy<Person, "namr">("namr");


const people: Person[] = [
    { name: "John", age: 30 },
    { name: "Jack", age: 27 }
];

const peopleSortedByAge = sortByAge(people);
const peopleSortedByName = sortByName(people);

Upvotes: 1

Related Questions