FlowJS - gives a type error because it cannot recognize the result of a `typeof` statement
up vote
0
down vote
favorite
The following code results in an error:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const isString = typeof next === 'string';
const toName = isString ? next : Object.keys(next)[0];
^ string [1] is not an object.
but getting rid of the isString
variable fixes it:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
I understand why, but I'm hoping that someone might offer a better solution. I need to reuse the isString
variable and would like to keep my code both DRY and SIMPLE (easy to read). So no "clever" (hacky) solutions please.
javascript flowtype
add a comment |
up vote
0
down vote
favorite
The following code results in an error:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const isString = typeof next === 'string';
const toName = isString ? next : Object.keys(next)[0];
^ string [1] is not an object.
but getting rid of the isString
variable fixes it:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
I understand why, but I'm hoping that someone might offer a better solution. I need to reuse the isString
variable and would like to keep my code both DRY and SIMPLE (easy to read). So no "clever" (hacky) solutions please.
javascript flowtype
Can you use nesting to run all of the string code in its own block, e.g.if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?
– loganfsmyth
yesterday
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
The following code results in an error:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const isString = typeof next === 'string';
const toName = isString ? next : Object.keys(next)[0];
^ string [1] is not an object.
but getting rid of the isString
variable fixes it:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
I understand why, but I'm hoping that someone might offer a better solution. I need to reuse the isString
variable and would like to keep my code both DRY and SIMPLE (easy to read). So no "clever" (hacky) solutions please.
javascript flowtype
The following code results in an error:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const isString = typeof next === 'string';
const toName = isString ? next : Object.keys(next)[0];
^ string [1] is not an object.
but getting rid of the isString
variable fixes it:
type NextItem = string | { [string]: string };
const next: NextItem = 'foo';
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
I understand why, but I'm hoping that someone might offer a better solution. I need to reuse the isString
variable and would like to keep my code both DRY and SIMPLE (easy to read). So no "clever" (hacky) solutions please.
javascript flowtype
javascript flowtype
edited 17 hours ago
asked yesterday
Ryan Wheale
12k44567
12k44567
Can you use nesting to run all of the string code in its own block, e.g.if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?
– loganfsmyth
yesterday
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago
add a comment |
Can you use nesting to run all of the string code in its own block, e.g.if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?
– loganfsmyth
yesterday
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago
Can you use nesting to run all of the string code in its own block, e.g.
if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?– loganfsmyth
yesterday
Can you use nesting to run all of the string code in its own block, e.g.
if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?– loganfsmyth
yesterday
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
Flow's refinements are generally based on direct checks at the time of use, so it will only ever see your isString
variable as a boolean
with no special meaning.
That leaves you with a few separate options:
- Tweak the control flow of your code so there are two clear branches, assuming there are many more checks for
isString
, you can always make a clear branch to handle both cases.
Inline the
typeof next === 'string'
check.
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
Use a predicate function to centralize the
isString
logic
function isString(arg: mixed): boolean %checks {
return typeof arg === "string";
}
const toName = isString(next) ? next : Object.keys(next)[0];
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Flow's refinements are generally based on direct checks at the time of use, so it will only ever see your isString
variable as a boolean
with no special meaning.
That leaves you with a few separate options:
- Tweak the control flow of your code so there are two clear branches, assuming there are many more checks for
isString
, you can always make a clear branch to handle both cases.
Inline the
typeof next === 'string'
check.
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
Use a predicate function to centralize the
isString
logic
function isString(arg: mixed): boolean %checks {
return typeof arg === "string";
}
const toName = isString(next) ? next : Object.keys(next)[0];
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
add a comment |
up vote
1
down vote
accepted
Flow's refinements are generally based on direct checks at the time of use, so it will only ever see your isString
variable as a boolean
with no special meaning.
That leaves you with a few separate options:
- Tweak the control flow of your code so there are two clear branches, assuming there are many more checks for
isString
, you can always make a clear branch to handle both cases.
Inline the
typeof next === 'string'
check.
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
Use a predicate function to centralize the
isString
logic
function isString(arg: mixed): boolean %checks {
return typeof arg === "string";
}
const toName = isString(next) ? next : Object.keys(next)[0];
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Flow's refinements are generally based on direct checks at the time of use, so it will only ever see your isString
variable as a boolean
with no special meaning.
That leaves you with a few separate options:
- Tweak the control flow of your code so there are two clear branches, assuming there are many more checks for
isString
, you can always make a clear branch to handle both cases.
Inline the
typeof next === 'string'
check.
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
Use a predicate function to centralize the
isString
logic
function isString(arg: mixed): boolean %checks {
return typeof arg === "string";
}
const toName = isString(next) ? next : Object.keys(next)[0];
Flow's refinements are generally based on direct checks at the time of use, so it will only ever see your isString
variable as a boolean
with no special meaning.
That leaves you with a few separate options:
- Tweak the control flow of your code so there are two clear branches, assuming there are many more checks for
isString
, you can always make a clear branch to handle both cases.
Inline the
typeof next === 'string'
check.
const toName = typeof next === 'string' ? next : Object.keys(next)[0];
Use a predicate function to centralize the
isString
logic
function isString(arg: mixed): boolean %checks {
return typeof arg === "string";
}
const toName = isString(next) ? next : Object.keys(next)[0];
answered 17 hours ago
loganfsmyth
99.4k18209181
99.4k18209181
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
add a comment |
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
The utility method (option 3) is the winner. I did not know about predicates in flowtype yet. Thanks!
– Ryan Wheale
46 mins ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53199219%2fflowjs-gives-a-type-error-because-it-cannot-recognize-the-result-of-a-typeof%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Can you use nesting to run all of the string code in its own block, e.g.
if (typeof next === 'string') { /* all the string stuff */ } else { /* all the object stuff */ }
?– loganfsmyth
yesterday
Maybe, that's a tangible solution. It results in more code (longer form of a ternary), but at least it works. Do you mind posting an answer, as that's the only viable solution I have found to this. Thanks!
– Ryan Wheale
17 hours ago