0

Suppose that i have an object like:

const obj = [
  { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"},
  { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"}
]

I want to create a function to order by createdAt, which is the only field i'm sure it will be in the object. The function will be something like:

export const sortArrayByCreatedAt = (arr: TypeArr) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

How can i define the type of arr?

Type TypeArr {
  createdAt: string
}

Is it good practice to define the type of the only known var?

I think that if someone else will see this function he will think that obj contains only createdAt, but i didn't find a better solution.

2
  • If you have 2 possible interfaces, you could define the parameter as Array<A | B>. If both of these interfaces have the createdAt property, your code should compile just fine. Commented Oct 25, 2022 at 8:25
  • interface TypeArr { createdAt: string; updatedAt?: string; animal?: string} and const obj: TypeArr[] = [...] Commented Oct 25, 2022 at 8:25

4 Answers 4

2

I would define my TypeArr as an interface and the sort method as a generic method. So it wouldn't change the return type.

export const sortArrayByCreatedAt = <T extends TypeArr>(arr: Array<T>) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

interface TypeArr{
    createdAt :string
}

const obj = [
  { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"},
  { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"}
]

const sorted = sortArrayByCreatedAt(obj);

Playground

Sign up to request clarification or add additional context in comments.

Comments

1

It seems like you are also returning the array which you pass to the function. Right now, the return type would only be TypeArr[] which does not reflect the additional properties in the objects.

I would make sortArrayByCreatedAt generic.

export const sortArrayByCreatedAt = <T extends { createdAt: string }[]>(arr: T): T => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

The input type will also be the return type now.

Comments

0

You can have optional properties in types or interfaces using a question mark ?:

type MyType = {
    createdAt: string;
    updatedAt?: string;
    animal?: string;
}
interface MyInterface {
    createdAt: string;
    updatedAt?: string;
    animal?: string;
}

If you are typing an array of the object, you would use MyType[] or MyInterface[] e.g.

export const sortArrayByCreatedAt = (arr: MyType[]) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

Comments

0

You can define an interface and use the question mark ? in front of optional properties:

interface TypeArr {
  createdAt: string
  updatedAt?: string
  animal?: string
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.