Flowtype extend object type
As JavaScript developer I'm new to type checking and I struggle to understand why this simple code is not working:
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
What I'm trying to achieve here is to have a method that accepts interface. This however gives me error: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'.
.
What I tried:
interface Animal // ...
- does not work.- Remove typing from
buddy
- it work's but I'm not satisfied. Sometimes I do want to have more strict type (so I know I'm dealing with dog not cat) but still use general method that accept any animal. - I tried changing
type: 'dog' | 'cat'
totype: string
- does not work. I would expect'dog'
string is subtype of generalstring
type but it's not. On the other hand even if it works it wouldn't be enough - sometimes I know that my app accepts only dogs and cats not any other animals.
Thanks for reading and I hope I can get some help from you guys! Here's live version: Try Flow - live example
javascript flowtype
add a comment |
As JavaScript developer I'm new to type checking and I struggle to understand why this simple code is not working:
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
What I'm trying to achieve here is to have a method that accepts interface. This however gives me error: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'.
.
What I tried:
interface Animal // ...
- does not work.- Remove typing from
buddy
- it work's but I'm not satisfied. Sometimes I do want to have more strict type (so I know I'm dealing with dog not cat) but still use general method that accept any animal. - I tried changing
type: 'dog' | 'cat'
totype: string
- does not work. I would expect'dog'
string is subtype of generalstring
type but it's not. On the other hand even if it works it wouldn't be enough - sometimes I know that my app accepts only dogs and cats not any other animals.
Thanks for reading and I hope I can get some help from you guys! Here's live version: Try Flow - live example
javascript flowtype
2
I've been able to find solution by actually specifing two explicit type definitions: forcat
anddog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!
– Ernest Nowacki
Nov 12 at 11:10
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. thisanimal.color
should throw, asCat
doesn't implement acolor
– Thomas
Nov 14 at 12:08
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks likeAnimal
now needsCat
type to be defined andCat
type needAnimal
type to be defined. So for now I'm rolling withtype Animal = Cat | Dog
.
– Ernest Nowacki
Nov 16 at 10:41
add a comment |
As JavaScript developer I'm new to type checking and I struggle to understand why this simple code is not working:
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
What I'm trying to achieve here is to have a method that accepts interface. This however gives me error: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'.
.
What I tried:
interface Animal // ...
- does not work.- Remove typing from
buddy
- it work's but I'm not satisfied. Sometimes I do want to have more strict type (so I know I'm dealing with dog not cat) but still use general method that accept any animal. - I tried changing
type: 'dog' | 'cat'
totype: string
- does not work. I would expect'dog'
string is subtype of generalstring
type but it's not. On the other hand even if it works it wouldn't be enough - sometimes I know that my app accepts only dogs and cats not any other animals.
Thanks for reading and I hope I can get some help from you guys! Here's live version: Try Flow - live example
javascript flowtype
As JavaScript developer I'm new to type checking and I struggle to understand why this simple code is not working:
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
What I'm trying to achieve here is to have a method that accepts interface. This however gives me error: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'.
.
What I tried:
interface Animal // ...
- does not work.- Remove typing from
buddy
- it work's but I'm not satisfied. Sometimes I do want to have more strict type (so I know I'm dealing with dog not cat) but still use general method that accept any animal. - I tried changing
type: 'dog' | 'cat'
totype: string
- does not work. I would expect'dog'
string is subtype of generalstring
type but it's not. On the other hand even if it works it wouldn't be enough - sometimes I know that my app accepts only dogs and cats not any other animals.
Thanks for reading and I hope I can get some help from you guys! Here's live version: Try Flow - live example
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
type Animal =
id: number,
name: string,
type: 'dog' ;
type Dog =
id: number,
name: string,
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
javascript flowtype
javascript flowtype
asked Nov 12 at 10:17
Ernest Nowacki
21616
21616
2
I've been able to find solution by actually specifing two explicit type definitions: forcat
anddog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!
– Ernest Nowacki
Nov 12 at 11:10
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. thisanimal.color
should throw, asCat
doesn't implement acolor
– Thomas
Nov 14 at 12:08
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks likeAnimal
now needsCat
type to be defined andCat
type needAnimal
type to be defined. So for now I'm rolling withtype Animal = Cat | Dog
.
– Ernest Nowacki
Nov 16 at 10:41
add a comment |
2
I've been able to find solution by actually specifing two explicit type definitions: forcat
anddog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!
– Ernest Nowacki
Nov 12 at 11:10
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. thisanimal.color
should throw, asCat
doesn't implement acolor
– Thomas
Nov 14 at 12:08
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks likeAnimal
now needsCat
type to be defined andCat
type needAnimal
type to be defined. So for now I'm rolling withtype Animal = Cat | Dog
.
– Ernest Nowacki
Nov 16 at 10:41
2
2
I've been able to find solution by actually specifing two explicit type definitions: for
cat
and dog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!– Ernest Nowacki
Nov 12 at 11:10
I've been able to find solution by actually specifing two explicit type definitions: for
cat
and dog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!– Ernest Nowacki
Nov 12 at 11:10
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. this
animal.color
should throw, as Cat
doesn't implement a color
– Thomas
Nov 14 at 12:08
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. this
animal.color
should throw, as Cat
doesn't implement a color
– Thomas
Nov 14 at 12:08
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks like
Animal
now needs Cat
type to be defined and Cat
type need Animal
type to be defined. So for now I'm rolling with type Animal = Cat | Dog
.– Ernest Nowacki
Nov 16 at 10:41
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks like
Animal
now needs Cat
type to be defined and Cat
type need Animal
type to be defined. So for now I'm rolling with type Animal = Cat | Dog
.– Ernest Nowacki
Nov 16 at 10:41
add a comment |
1 Answer
1
active
oldest
votes
You have to make the Animal
type an interface since it's describing your types implementations as a "parent". And it would make sense if you enforce it by extending your Dog
type via a union since that's the point of using typings to reach a stronger type-checking.
This can be written like this:
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
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
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53260023%2fflowtype-extend-object-type%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You have to make the Animal
type an interface since it's describing your types implementations as a "parent". And it would make sense if you enforce it by extending your Dog
type via a union since that's the point of using typings to reach a stronger type-checking.
This can be written like this:
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
add a comment |
You have to make the Animal
type an interface since it's describing your types implementations as a "parent". And it would make sense if you enforce it by extending your Dog
type via a union since that's the point of using typings to reach a stronger type-checking.
This can be written like this:
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
add a comment |
You have to make the Animal
type an interface since it's describing your types implementations as a "parent". And it would make sense if you enforce it by extending your Dog
type via a union since that's the point of using typings to reach a stronger type-checking.
This can be written like this:
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
You have to make the Animal
type an interface since it's describing your types implementations as a "parent". And it would make sense if you enforce it by extending your Dog
type via a union since that's the point of using typings to reach a stronger type-checking.
This can be written like this:
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
/* @flow */
interface Animal
id: number,
name: string,
type: 'dog' ;
type Dog = Animal &
type: 'dog',
color: string
;
function printAnimal(animal: Animal): string
return `$animal.type: $animal.name`;
const buddy: Dog =
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
printAnimal(buddy);
answered Nov 19 at 2:44
Ivan Gabriele
3,29622444
3,29622444
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53260023%2fflowtype-extend-object-type%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I've been able to find solution by actually specifing two explicit type definitions: for
cat
anddog
and then create a type out of those two with disjoint union. Here's live version. Still looking for better ways!– Ernest Nowacki
Nov 12 at 11:10
after playing around a bit, I found this cyclic weirdness to be working: live. Well kind of, because imo. this
animal.color
should throw, asCat
doesn't implement acolor
– Thomas
Nov 14 at 12:08
Thanks for your input @Thomas ! It's definitely nice that your solution is not throwing error however I don't like cyclomatic complexity - it looks like
Animal
now needsCat
type to be defined andCat
type needAnimal
type to be defined. So for now I'm rolling withtype Animal = Cat | Dog
.– Ernest Nowacki
Nov 16 at 10:41