-
-
Notifications
You must be signed in to change notification settings - Fork 253
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
TypeScript doesn't correctly narrow types and detect unreachable code after calling redirect()
#823
Comments
That's really strange, thanks for the report. Do you have an idea why this works for I've added a reproduction in #824. |
#149 (comment) |
maybe because Typescript's |
You can refer to this issue. microsoft/TypeScript#36753 For example, if there is a function // Function declaration
function test1(): never {
throw new Error('test');
}
function main1() {
test1();
console.log('test');
} But if you declare a function using arrow function like
// Arrow function
const test2 = (): never => {
throw new Error('test');
};
function main2() {
test2();
console.log('test');
} But CFA works when you explicit type like
// Arrow function with type annotation
const test3: () => never = () => {
throw new Error('test');
};
function main3() {
test3();
console.log('test');
} |
@A7med3bdulBaset Your solution here #149 (comment) looks good! The lines on my example can be changed like this. // From this
export function redirect(...params: Parameters<typeof navigation.redirect>): never {
return navigation.redirect(...params);
}
// To this
export const redirect: typeof navigation.redirect = navigation.redirect; |
@amannn Also, the reason why next/navigation works is next's redirect is declared like this. It's a function not an arrow function. export declare function redirect(url: string, type?: RedirectType): never; |
@MinSeungHyun Do you know how this could be fixed in The relevant files would be here:
… with currently failing tests in #824. I tried a type annotation with an arrow function but that doesn't seem to change anything: // createSharedPathnamesNavigation.tsx
const test: (...args: Parameters<typeof redirect>) => never = redirect; The original |
I've already tried to fix and create PR for it, but I couldn't find any simple solution 🥲 export const {Link, redirect, usePathname, useRouter} =
createLocalizedPathnamesNavigation({
locales,
localePrefix,
pathnames
}); |
At most, it's a Typescript bug |
Seems like this gets reported time and time again on the TypeScript issue tracker:
I guess the best for the time being is the approach mentioned by @AhmedBaset and @MinSeungHyun from above: const {redirect: _redirect} = createNavigation(routing);
// Help TypeScript detect unreachable code
export const redirect: typeof _redirect = _redirect; (there's an expandable section in the docs on this now) |
redirect()
returned from createSharedPathnamesNavigation
redirect()
redirect()
redirect()
redirect()
redirect()
redirect()
redirect()
Description
When I use next/navigation's redirect, the type of userId is successfully narrowed to string because if userId is undefined it calls redirect() whose return type is never.
But when I use redirect from
createSharedPathnamesNavigation
, it's not working.This is because of typescript's designed limitation. microsoft/TypeScript#36753
So I'm using redirect like this on my project. I re-declared redirect as a function not a const.
I think it should work by default when using next-intl's redirect as next's default redirect does.
Mandatory reproduction URL (CodeSandbox or GitHub repository)
https://codesandbox.io/p/devbox/next-intl-bug-template-app-forked-fp6873
Reproduction description
Steps to reproduce:
Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.
onuserId2
default/page.tsx
,intl2/page.tsx
, it works fine,Expected behaviour
The type error should not be occurred like other files.
The text was updated successfully, but these errors were encountered: