Issue
In the code below:
enum FirstSourceTopicAliases {
Topic = 'topic',
TopicText = 'topic_text',
TopicLink = 'topic_link',
}
enum SecondSourceTopicAliases {
Topic = 'title',
TopicText = 'body',
TopicLink = 'link',
}
interface FirstSourceTopic {
[FirstSourceTopicAliases.Topic]: string,
[FirstSourceTopicAliases.TopicText]: string,
[FirstSourceTopicAliases.TopicLink]: string,
}
interface SecondSourceTopic {
[SecondSourceTopicAliases.Topic]: string,
[SecondSourceTopicAliases.TopicText]: string,
[SecondSourceTopicAliases.TopicLink]: string,
}
type Topic = FirstSourceTopic | SecondSourceTopic
const parseTopic = (topic: Topic) => {
const parsedTopic = {
topic: 'parsed' + topic.topic // or topic.title
topicText: 'parsed' + topic.topic_text // or topic.body
topicLink: 'parsed' + topic.topic_link, // or topic.link
}
return parsedTopic
}
const firstSourceTopic: FirstSourceTopic = {
topic: 'some topic',
topic_text: 'some topic text',
topic_link: 'some topic link',
}
const secondSourceTopic: SecondSourceTopic = {
title: 'some topic',
body: 'some topic text',
link: 'some topic link',
}
const parsedTopic = parseTopic(firstSourceTopic)
console.log(parsedTopic)
Is it possible to make parseRow function generic enough so that it knows what key to extract from topic object that is passed to it? Currently the compiler will complain if I choose one of the attributes because the attribute is not present on the other type.
Solution
You could add a disciminator field property to disambiguate between your types (currently you have no intersection), e.g.
enum FirstSourceTopicAliases {
Topic = 'topic',
TopicText = 'topic_text',
TopicLink = 'topic_link',
}
enum SecondSourceTopicAliases {
Topic = 'title',
TopicText = 'body',
TopicLink = 'link',
}
interface FirstSourceTopic {
kind:'first',
[FirstSourceTopicAliases.Topic]: string,
[FirstSourceTopicAliases.TopicText]: string,
[FirstSourceTopicAliases.TopicLink]: string,
}
interface SecondSourceTopic {
kind:'second',
[SecondSourceTopicAliases.Topic]: string,
[SecondSourceTopicAliases.TopicText]: string,
[SecondSourceTopicAliases.TopicLink]: string,
}
type Topic = FirstSourceTopic | SecondSourceTopic
const parseTopic = <T extends FirstSourceTopic | SecondSourceTopic>(topic: T) => {
if (topic.kind==='first') {
return {
topic: 'parsed' + topic.topic ,
topicText: 'parsed' + topic.topic_text,
topicLink: 'parsed' + topic.topic_link,
}}
return {
topic: 'parsed' + topic.title ,
topicText: 'parsed' + topic.body,
topicLink: 'parsed' + topic.link,
}
}
const firstSourceTopic: FirstSourceTopic = {
kind:'first',
topic: 'some topic',
topic_text: 'some topic text',
topic_link: 'some topic link',
}
const secondSourceTopic: SecondSourceTopic = {
kind:'second',
title: 'some topic',
body: 'some topic text',
link: 'some topic link',
}
const parsedTopic = parseTopic(firstSourceTopic)
console.log(parsedTopic)
Answered By - Damian Green
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.