{"id":2012,"date":"2017-05-01T16:03:25","date_gmt":"2017-05-01T16:03:25","guid":{"rendered":"http:\/\/salientsoft.co.uk\/?p=2012"},"modified":"2018-10-10T17:15:57","modified_gmt":"2018-10-10T17:15:57","slug":"typescript-duck-typing-error-when-casting-a-reference","status":"publish","type":"post","link":"https:\/\/salientsoft.co.uk\/?p=2012","title":{"rendered":"Typescript duck typing error when casting a reference."},"content":{"rendered":"<p>The following code fragment in a dao gave an error when casting the response json. The cause is not clear, but 2 code variations were tried:-<\/p>\n<blockquote>\n<pre>\/\/API calls<br \/>  getFeatures(): Observable&lt;FeaturesSearchResult&gt; {<br \/>      return this.http.get(this.queryFeatures())<\/pre>\n<pre>      \/\/ *** This version originally failed citing that property total_rows did not exist<br \/>      .map(response =&gt; {return &lt;FeaturesSearchResult&gt;(response.json())});<br \/>  }<\/pre>\n<\/blockquote>\n<p>I then tried using the  \u201cas\u201d operator for the cast instead of the &lt;&gt; syntax. This worked. Strangely, right at the end I managed to get an example with the\u201d&lt;&gt;\u201d syntax working too, but the reason and differences were not at all clear.<br \/>\nHowever, I noted that the latter is also the preferred syntax now, as unlike the \u201c&lt;&gt;\u201d syntax it is also compatible with JSX\/.tsx syntax (JSX is an embeddable React xml-like syntax which transforms into JavaScript)<\/font><br \/>\nSee <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/What's-new-in-TypeScript#new-tsx-file-extension-and-as-operator\">here<\/a> for details on JSX\/.tsx, and on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/React_(JavaScript_library)#JSX\">React wikipedia entry<\/a>. The working code fragment follows:-<\/p>\n<blockquote>\n<pre>\/\/API calls<br \/>  getFeatures(): Observable&lt;FeaturesSearchResult&gt; {<br \/>      return this.http.get(this.queryFeatures())\/\/ *** This version originally failed citing that property total_rows did not exist<br \/><\/pre>\n<pre>      \/\/ *** This version worked by using the \u201cas \u2026\u201d syntax for casting rather than &lt;&gt;<br \/>      .map(response =&gt; {return response.json() as FeaturesSearchResult});<br \/>  }<\/pre>\n<\/blockquote>\n<p>The full listing of the code for the working version (less imports for brevity) follows:-<\/p>\n<pre><strong><u>features-dao.ts<\/u><\/strong><\/pre>\n<blockquote>\n<pre>@Injectable()<br \/>export class FeaturesDao {<br \/>  constructor(private appConfig: AppConfig,<br \/>              private http: Http) {}<br \/><br \/>\/\/API calls<br \/>  getFeatures(): Observable&lt;FeaturesSearchResult&gt; {<br \/>      return this.http.get(this.queryFeatures())<br \/>      .map(response =&gt; {return response.json() as FeaturesSearchResult});<br \/>  }<br \/><br \/>\/\/API query definitions<br \/>  queryFeatures(): string {<br \/>    return `${this.appConfig.apiBase}_design\/places\/_view\/featuresByOrdinal?include_docs=true`;<br \/>  }<br \/><br \/>}<br \/>export interface FeaturesSearchResult extends CouchDBResult&lt;FeaturesSearchResultRow&gt;  {}<br \/>export interface FeaturesSearchResultRow extends CouchDBResultRow&lt;number[], any, FeatureDoc&gt; {}<br \/><\/pre>\n<\/blockquote>\n<pre><strong><u>couchdb-result.ts<\/u><\/strong><\/pre>\n<blockquote>\n<pre>export interface CouchDBResult&lt;R extends CouchDBResultRow&lt;any,any,any&gt;&gt; {<br \/>  total_rows: number;<br \/>  offset: number;<br \/>  rows: R[];<br \/>}<br \/><br \/>export interface CouchDBResultRow&lt;K,V,D&gt; {<br \/>  id: string;<br \/>  key: K;<br \/>  value: V;<br \/>  doc?: D;<br \/>}<br \/><\/pre>\n<\/blockquote>\n<pre><strong><u>feature-doc.ts<\/u><\/strong><\/pre>\n<blockquote>\n<pre>export interface FeatureDoc extends CouchDBDoc {<br \/>  ordinal: number;<br \/>  name: string;<br \/>  description: string;<br \/>  searchable: boolean;<br \/>  rateable: boolean;<br \/>}<br \/><\/pre>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>The following code fragment in a dao gave an error when casting the response json. The cause is not clear, but 2 code variations were tried:- \/\/API calls getFeatures(): Observable&lt;FeaturesSearchResult&gt; { return this.http.get(this.queryFeatures()) \/\/ *** This version originally failed citing that property total_rows did not exist .map(response =&gt; {return &lt;FeaturesSearchResult&gt;(response.json())}); } I then tried using [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[198,207],"tags":[13,40,16,208],"_links":{"self":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2012"}],"collection":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2012"}],"version-history":[{"count":6,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2012\/revisions"}],"predecessor-version":[{"id":2018,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2012\/revisions\/2018"}],"wp:attachment":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2012"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2012"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2012"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}