0

I have a composable function that returns an array of objects and a function that received a string and doesn't return anything.

The below code 'works' and doesn't throw any errors.

import { ref } from "vue";
import { useRoute } from "vue-router";

interface RouterHelper {
    children: any;
    getChildrenOf: (name: string) => void;
}

export const routerHelper = (): RouterHelper => {
    const route = useRoute();
    const children = ref();

    const getChildrenOf = (name: string) => {
        children.value = route?.matched
            ?.find((r) => r.name === name)
            ?.children.filter((c) => c.alias);
    };

    return { children, getChildrenOf };
};

However, it isn't entirely accurate. For example, when declaring the children ref, it should be :

const children = ref([]);

But I get this error:

TS2322: Type 'RouteRecordRaw[] | undefined' is not assignable to type 'never[]'.

Also, in the interface, I have to use any instead of the proper type of [] for the children property.

Please note, I'm very new to Typescript, so when I say 'proper' take it with a grain of salt.

Any way I can make this code better and not use catch all's like any?

Thank you!

0

1 Answer 1

1

The ref is ultimately assigned to a subset of route.matched[].children, which is of type RouteRecordRaw[].

Optional chaining (in route.matched.find(...)?.children) short-circuits to undefined, so if Array.prototype.find() doesn't find a match, the ref type would be undefined. Otherwise, it would be RouteRecordRaw[].

Therefore, the ref's value field is typed as RouteRecordRaw[] | undefined. Finally, the return value of ref() is of type Ref<T> (where T is the type of the argument to ref()), so the type of children is Ref<RouteRecordRaw[] | undefined>.

import { ref, Ref } from "vue";
import { useRoute, RouteRecordRaw } from "vue-router";

interface RouterHelper {
                         👇
    children: Ref<RouteRecordRaw[] | undefined>;
    getChildrenOf: (name: string) => void;
}

export const routerHelper = (): RouterHelper => {
    const route = useRoute();
                             👇
    const children: RouterHelper['children'] = ref([]);

    const getChildrenOf = (name: string) => {
        children.value = route.matched
            .find((r) => r.name === name)
            ?.children.filter((c) => c.alias);
    };

    return { children, getChildrenOf };
};
Sign up to request clarification or add additional context in comments.

2 Comments

I ended up changing the logic quite a bit, but that RouteRecordRaw still ended up helping so putting this as an answer. Any chance you could explain the reasoning for this? If you have a ref always use Ref<something something>?
@RizaKhan The return value of ref() is the generic Ref<T>. T can be inferred from primitive values (strings and numbers), but not for complex types (object arrays in this case). See updated answer for how I arrived at the final type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.