typescript Property 'options' does not exist on type of Union type












1















I have a couple of interface and a union type:



export interface FieldOptions {
value: string | number;
viewValue: string;
}

export interface BaseField {
id: string;
derived?: boolean;
required?: boolean;
}

export interface NumberField extends BaseField {
type: 'number';
decimals: number;
}
export interface SelectField extends BaseField {
type: 'select' | 'select-multi';
options: FieldOptions;
source?: string;
}

export type Field = NumberField | SelectField;


As I understand that when I use my union type Field, it mains a field can be either Number or Select.



With that knowledge, I have a function in my Angular Component



getField( key: string ): Field {
return this.fields.filter( el => el.id === key )[ 0 ];
}

getFieldVersion2( key: string ): any {
const field = this.fields.filter( el => el.id === key )[ 0 ];
if ( (<SelectField>field).options ) {
return field as SelectField;
} else {
return field as Field;
}
}


With only the function getField which is called in my template to get a Field object, in this case a Select with an Options array of view/viewValues, I get a build error on TS:



Property 'options' does not exist on type 'Field'.
Property 'options' does not exist on type 'NumberField'.


In my understanding Field is a union type of either Number or Select. One of those has an options property, the other one doesn't.



So I created getFieldVersion2 to hopefully solve the issue. However, unless I add any as a result type of my function, it will trigger a build error.



The template where the options are being used which triggers the compile error:



<mat-form-field  class="input">
<mat-select formControlName="state">
<mat-option *ngFor="let option of getField( 'state' ).options" [value]="option.value">
{{option.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>


What is going on, and what should I do better?










share|improve this question

























  • Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

    – dtanabe
    Jan 19 at 3:16











  • exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

    – Mattijs
    Jan 20 at 4:07
















1















I have a couple of interface and a union type:



export interface FieldOptions {
value: string | number;
viewValue: string;
}

export interface BaseField {
id: string;
derived?: boolean;
required?: boolean;
}

export interface NumberField extends BaseField {
type: 'number';
decimals: number;
}
export interface SelectField extends BaseField {
type: 'select' | 'select-multi';
options: FieldOptions;
source?: string;
}

export type Field = NumberField | SelectField;


As I understand that when I use my union type Field, it mains a field can be either Number or Select.



With that knowledge, I have a function in my Angular Component



getField( key: string ): Field {
return this.fields.filter( el => el.id === key )[ 0 ];
}

getFieldVersion2( key: string ): any {
const field = this.fields.filter( el => el.id === key )[ 0 ];
if ( (<SelectField>field).options ) {
return field as SelectField;
} else {
return field as Field;
}
}


With only the function getField which is called in my template to get a Field object, in this case a Select with an Options array of view/viewValues, I get a build error on TS:



Property 'options' does not exist on type 'Field'.
Property 'options' does not exist on type 'NumberField'.


In my understanding Field is a union type of either Number or Select. One of those has an options property, the other one doesn't.



So I created getFieldVersion2 to hopefully solve the issue. However, unless I add any as a result type of my function, it will trigger a build error.



The template where the options are being used which triggers the compile error:



<mat-form-field  class="input">
<mat-select formControlName="state">
<mat-option *ngFor="let option of getField( 'state' ).options" [value]="option.value">
{{option.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>


What is going on, and what should I do better?










share|improve this question

























  • Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

    – dtanabe
    Jan 19 at 3:16











  • exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

    – Mattijs
    Jan 20 at 4:07














1












1








1








I have a couple of interface and a union type:



export interface FieldOptions {
value: string | number;
viewValue: string;
}

export interface BaseField {
id: string;
derived?: boolean;
required?: boolean;
}

export interface NumberField extends BaseField {
type: 'number';
decimals: number;
}
export interface SelectField extends BaseField {
type: 'select' | 'select-multi';
options: FieldOptions;
source?: string;
}

export type Field = NumberField | SelectField;


As I understand that when I use my union type Field, it mains a field can be either Number or Select.



With that knowledge, I have a function in my Angular Component



getField( key: string ): Field {
return this.fields.filter( el => el.id === key )[ 0 ];
}

getFieldVersion2( key: string ): any {
const field = this.fields.filter( el => el.id === key )[ 0 ];
if ( (<SelectField>field).options ) {
return field as SelectField;
} else {
return field as Field;
}
}


With only the function getField which is called in my template to get a Field object, in this case a Select with an Options array of view/viewValues, I get a build error on TS:



Property 'options' does not exist on type 'Field'.
Property 'options' does not exist on type 'NumberField'.


In my understanding Field is a union type of either Number or Select. One of those has an options property, the other one doesn't.



So I created getFieldVersion2 to hopefully solve the issue. However, unless I add any as a result type of my function, it will trigger a build error.



The template where the options are being used which triggers the compile error:



<mat-form-field  class="input">
<mat-select formControlName="state">
<mat-option *ngFor="let option of getField( 'state' ).options" [value]="option.value">
{{option.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>


What is going on, and what should I do better?










share|improve this question
















I have a couple of interface and a union type:



export interface FieldOptions {
value: string | number;
viewValue: string;
}

export interface BaseField {
id: string;
derived?: boolean;
required?: boolean;
}

export interface NumberField extends BaseField {
type: 'number';
decimals: number;
}
export interface SelectField extends BaseField {
type: 'select' | 'select-multi';
options: FieldOptions;
source?: string;
}

export type Field = NumberField | SelectField;


As I understand that when I use my union type Field, it mains a field can be either Number or Select.



With that knowledge, I have a function in my Angular Component



getField( key: string ): Field {
return this.fields.filter( el => el.id === key )[ 0 ];
}

getFieldVersion2( key: string ): any {
const field = this.fields.filter( el => el.id === key )[ 0 ];
if ( (<SelectField>field).options ) {
return field as SelectField;
} else {
return field as Field;
}
}


With only the function getField which is called in my template to get a Field object, in this case a Select with an Options array of view/viewValues, I get a build error on TS:



Property 'options' does not exist on type 'Field'.
Property 'options' does not exist on type 'NumberField'.


In my understanding Field is a union type of either Number or Select. One of those has an options property, the other one doesn't.



So I created getFieldVersion2 to hopefully solve the issue. However, unless I add any as a result type of my function, it will trigger a build error.



The template where the options are being used which triggers the compile error:



<mat-form-field  class="input">
<mat-select formControlName="state">
<mat-option *ngFor="let option of getField( 'state' ).options" [value]="option.value">
{{option.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>


What is going on, and what should I do better?







angular typescript union-types






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 20 at 4:10







Mattijs

















asked Jan 19 at 3:11









MattijsMattijs

1,80232026




1,80232026













  • Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

    – dtanabe
    Jan 19 at 3:16











  • exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

    – Mattijs
    Jan 20 at 4:07



















  • Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

    – dtanabe
    Jan 19 at 3:16











  • exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

    – Mattijs
    Jan 20 at 4:07

















Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

– dtanabe
Jan 19 at 3:16





Seems like the error you're encountering is code that tries to actually use getField and possibly read the options property that may or may not exist; can you post that code as well? getFieldVersion2 doesn't really do anything differently than getField at runtime because all of the TypeScript types you declared in your example disappear when compiled down to JavaScript.

– dtanabe
Jan 19 at 3:16













exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

– Mattijs
Jan 20 at 4:07





exactly. However during compile time of typescript, the compiler is happy with getFieldVerstion2. I will amend my question and add the tempalte code

– Mattijs
Jan 20 at 4:07












1 Answer
1






active

oldest

votes


















1














You created an interface that does not have an "options" property. You then set your "Field" type equal to that interface (or potentially equal to another interface that does have the "options" property).



You are then attempting to call the "options" property that may or may not exist. This is why you are receiving the ts error when compiling.



Switching the return type to "any" works because the compiler will not try to guess the type of object you are returning (therefore it is plausible that "options" will be a valid property and therefore no error should be thrown).



If you are going to call the "options" property on the "Field" type, you should make sure it exists before trying to compile your ts script.



Perhaps updating your methods to "getSelectField" and "getNumberField" would be a better option....but of course there are multiple ways you could handle this.






share|improve this answer


























  • isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

    – Mattijs
    Jan 21 at 6:17











  • okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

    – Mattijs
    Jan 21 at 6:38











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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54263755%2ftypescript-property-options-does-not-exist-on-type-of-union-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









1














You created an interface that does not have an "options" property. You then set your "Field" type equal to that interface (or potentially equal to another interface that does have the "options" property).



You are then attempting to call the "options" property that may or may not exist. This is why you are receiving the ts error when compiling.



Switching the return type to "any" works because the compiler will not try to guess the type of object you are returning (therefore it is plausible that "options" will be a valid property and therefore no error should be thrown).



If you are going to call the "options" property on the "Field" type, you should make sure it exists before trying to compile your ts script.



Perhaps updating your methods to "getSelectField" and "getNumberField" would be a better option....but of course there are multiple ways you could handle this.






share|improve this answer


























  • isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

    – Mattijs
    Jan 21 at 6:17











  • okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

    – Mattijs
    Jan 21 at 6:38
















1














You created an interface that does not have an "options" property. You then set your "Field" type equal to that interface (or potentially equal to another interface that does have the "options" property).



You are then attempting to call the "options" property that may or may not exist. This is why you are receiving the ts error when compiling.



Switching the return type to "any" works because the compiler will not try to guess the type of object you are returning (therefore it is plausible that "options" will be a valid property and therefore no error should be thrown).



If you are going to call the "options" property on the "Field" type, you should make sure it exists before trying to compile your ts script.



Perhaps updating your methods to "getSelectField" and "getNumberField" would be a better option....but of course there are multiple ways you could handle this.






share|improve this answer


























  • isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

    – Mattijs
    Jan 21 at 6:17











  • okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

    – Mattijs
    Jan 21 at 6:38














1












1








1







You created an interface that does not have an "options" property. You then set your "Field" type equal to that interface (or potentially equal to another interface that does have the "options" property).



You are then attempting to call the "options" property that may or may not exist. This is why you are receiving the ts error when compiling.



Switching the return type to "any" works because the compiler will not try to guess the type of object you are returning (therefore it is plausible that "options" will be a valid property and therefore no error should be thrown).



If you are going to call the "options" property on the "Field" type, you should make sure it exists before trying to compile your ts script.



Perhaps updating your methods to "getSelectField" and "getNumberField" would be a better option....but of course there are multiple ways you could handle this.






share|improve this answer















You created an interface that does not have an "options" property. You then set your "Field" type equal to that interface (or potentially equal to another interface that does have the "options" property).



You are then attempting to call the "options" property that may or may not exist. This is why you are receiving the ts error when compiling.



Switching the return type to "any" works because the compiler will not try to guess the type of object you are returning (therefore it is plausible that "options" will be a valid property and therefore no error should be thrown).



If you are going to call the "options" property on the "Field" type, you should make sure it exists before trying to compile your ts script.



Perhaps updating your methods to "getSelectField" and "getNumberField" would be a better option....but of course there are multiple ways you could handle this.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 20 at 5:03

























answered Jan 20 at 4:57









user2263572user2263572

3,08132142




3,08132142













  • isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

    – Mattijs
    Jan 21 at 6:17











  • okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

    – Mattijs
    Jan 21 at 6:38



















  • isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

    – Mattijs
    Jan 21 at 6:17











  • okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

    – Mattijs
    Jan 21 at 6:38

















isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

– Mattijs
Jan 21 at 6:17





isn't what I am doing in getFieldVersion2 a form of type checking and returning the correct Interface? It still doesn't work unless I return any from that function

– Mattijs
Jan 21 at 6:17













okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

– Mattijs
Jan 21 at 6:38





okay, I did realize I the getField function is only used for fields with options, so I can make it more specific and call it getOptionsField which returns a type of SelectField (or later on a union type of RadioField or SelectField). I was just a bit intrigued to see the TS error in the template.

– Mattijs
Jan 21 at 6:38


















draft saved

draft discarded




















































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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54263755%2ftypescript-property-options-does-not-exist-on-type-of-union-type%23new-answer', 'question_page');
}
);

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







Popular posts from this blog

Liquibase includeAll doesn't find base path

How to use setInterval in EJS file?

Petrus Granier-Deferre