You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Assigning window.location after 5.8.2 upgrade fails #61335
Unable to assign window.location typescript 5.8.2
error TS2322: Type 'Location' is not assignable to type 'string & Location'.
Type 'Location' is not assignable to type 'string'.
How can anything satisfy the type string & Location? Was it supposed to be string | Location instead?
Reacted by Chaz Gatian, Jacob Groß, Ben Hayward, Dylan Gattey, BreamIsAFish, Kai, Shelagh-Lewins, Dmitriy Pushkov, Dan Minshew, Phil Wolstenholme and 2 more
Independent of whether or not this is a bug/regression: Shouldn't window.location.href = otherWindow.location.href do pretty much what you'd expect in most if not all of the cases?
This is hitting us in our test files where we will often override window.location to mock it in order to test client-side JavaScript behaviour like this:
Jake Bailey (@jakebailey)Ryan Cavanaugh (@RyanCavanaugh) sorry for tagging but this is a blocker for some codebases for upgrading to more recent TS versions, unless you add hundreds of ts-ignores. Is a fix planned, should someone make a PR or any other plans (it's been a month and no updates)?
I can imagine that the type being string & Location is itself a problem (probably some known issue with getters/setters; you'll note that the DOM types do not actually have this type anywhere, so it must be created by the checker), it seems to me that window.location = window.location is not actually legal, no?
Is this only working at runtime due to coercion to string since Location.toString() gives a string? I can't see how window.location = { ...anything } should work, as that wouldn't even have a toString.
Is this only working at runtime due to coercion to string since Location.toString() gives a string? I can't see how window.location = { ...anything } should work, as that wouldn't even have a toString.
Yes, as far as I can tell from MDN and the spec. Writes to window.location are effectively forwarded to window.location.href, which coerces to a string.
window.location = window.location is effectively window.location.href = window.location.toString(). Which works on browsers, but only with two magics under the hood:
location.href: The window.location setter is overriden so that the value goes to window.location.href instead.
location.toString(): Given that location.href expects string, any passed value will be implicitly stringified.
The first magic is what's supported by microsoft/TypeScript-DOM-lib-generator#1838. For the second magic, I think in general implicit stringification is not supported, if you want to pass a string then you should explicitly do so.
And window.location = window.location is just weird, maybe do location.reload() instead? If you feel strongly about the current code, you can do window.location.href = window.location.href which includes no magic.
Tom HT (@tomh-t) where should that be placed? Ben Ilegbodu (@benmvp)posted a similar fix a few years ago, but I can't either yours or his working. Typescript vis VS Code shows a missing property assignment near the end of the block. I tried at the top of the describe block, as well as inside the beforeEach block.
Andy Matthews (@commadelimited) - looks like a small syntax error you need to fix. I wouldn't trust a copy & paste in a github comment character for character - I have to edit it in here to avoid sharing irrelevant code and writing code in a comment is susceptible to syntax errors (missing curly)
Activity
MartinJohns commentedon Mar 4, 2025
Related: #48949
chrisvltn commentedon Mar 4, 2025
Had the same issue when upgrading to the new version.
A similar workaround to this one worked for me:
I see the PR #60987 added this part:
Seems to be the cause of the change, as
set locationexpects astring, butglobalThis['location']expects aLocationreifi commentedon Mar 5, 2025
A pain for old style iframe prevention - ts-ignore helps
onlywei commentedon Mar 13, 2025
How can anything satisfy the type
string & Location? Was it supposed to bestring | Locationinstead?clemens commentedon Mar 31, 2025
Independent of whether or not this is a bug/regression: Shouldn't
window.location.href = otherWindow.location.hrefdo pretty much what you'd expect in most if not all of the cases?philwolstenholme commentedon Mar 31, 2025
This is hitting us in our test files where we will often override
window.locationto mock it in order to test client-side JavaScript behaviour like this:kurtextrem commentedon Apr 8, 2025
Jake Bailey (@jakebailey) Ryan Cavanaugh (@RyanCavanaugh) sorry for tagging but this is a blocker for some codebases for upgrading to more recent TS versions, unless you add hundreds of ts-ignores. Is a fix planned, should someone make a PR or any other plans (it's been a month and no updates)?
jakebailey commentedon Apr 8, 2025
https://developer.mozilla.org/en-US/docs/Web/API/Window/location says that reading the variable gives a
Locationobject, but that you can write a string to the variable.I can imagine that the type being
string & Locationis itself a problem (probably some known issue with getters/setters; you'll note that the DOM types do not actually have this type anywhere, so it must be created by the checker), it seems to me thatwindow.location = window.locationis not actually legal, no?Is this only working at runtime due to coercion to string since
Location.toString()gives a string? I can't see howwindow.location = { ...anything }should work, as that wouldn't even have atoString.The change came from: microsoft/TypeScript-DOM-lib-generator#1838
Kagami Sascha Rosylight (@saschanaz)
snarbles2 commentedon Apr 8, 2025
Yes, as far as I can tell from MDN and the spec. Writes to
window.locationare effectively forwarded towindow.location.href, which coerces to a string.saschanaz commentedon Apr 8, 2025
window.location = window.locationis effectivelywindow.location.href = window.location.toString(). Which works on browsers, but only with two magics under the hood:location.href: Thewindow.locationsetter is overriden so that the value goes towindow.location.hrefinstead.location.toString(): Given thatlocation.hrefexpects string, any passed value will be implicitly stringified.The first magic is what's supported by microsoft/TypeScript-DOM-lib-generator#1838. For the second magic, I think in general implicit stringification is not supported, if you want to pass a string then you should explicitly do so.
And
window.location = window.locationis just weird, maybe dolocation.reload()instead? If you feel strongly about the current code, you can dowindow.location.href = window.location.hrefwhich includes no magic.saschanaz commentedon Apr 8, 2025
But the other part of me says maybe we should be less strict and allow passing
Locationwhere URLs are expected, as done in microsoft/TypeScript-DOM-lib-generator@2bffd44.Shelagh-Lewins commentedon Apr 28, 2025
I note that this code gives a TypeScript error, which doesn't seem like it can be intentional?
window.location = window.location;tomh-t commentedon May 8, 2025
If you're here because you're stubbing some window location properties - you can bypass the assignment type check:
For example with a
jeststub:commadelimited commentedon Jun 26, 2025
Tom HT (@tomh-t) where should that be placed? Ben Ilegbodu (@benmvp) posted a similar fix a few years ago, but I can't either yours or his working. Typescript vis VS Code shows a missing property assignment near the end of the block. I tried at the top of the describe block, as well as inside the beforeEach block.
tomh-t commentedon Jun 30, 2025
Andy Matthews (@commadelimited) - looks like a small syntax error you need to fix. I wouldn't trust a copy & paste in a github comment character for character - I have to edit it in here to avoid sharing irrelevant code and writing code in a comment is susceptible to syntax errors (missing curly)
But anyway - we're using this in a helper
And then in any test
commadelimited commentedon Jun 30, 2025
Thanks my friend, I'll give that a shot...appreciated.