Typescript: ts-check Issue with inline style attributes on JSX component not assignable

Created on 25 Sep 2017  路  6Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.4.1

Code

// @ts-check
import * as React from "react";

const styles = {
  search: {
    position: "relative",
  }
}

const Foo = () => (
  <div style={styles.search}></div>
);

Expected behavior:
Everything should be 馃憣

Actual behavior:
Getting a type error...

[js]
Type '{ style: { [x: string]: any; position: string; }; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Type '{ style: { [x: string]: any; position: string; }; }' is not assignable to type 'HTMLAttributes<HTMLDivElement>'.
    Types of property 'style' are incompatible.
      Type '{ [x: string]: any; position: string; }' is not assignable to type 'CSSProperties'.
[js]
Type '{ style: { [x: string]: any; position: string; }; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Type '{ style: { [x: string]: any; position: string; }; }' is not assignable to type 'HTMLAttributes<HTMLDivElement>'.
    Types of property 'style' are incompatible.
      Type '{ [x: string]: any; position: string; }' is not assignable to type 'CSSProperties'.
        Types of property 'position' are incompatible.
          Type 'string' is not assignable to type '"relative" | "initial" | "inherit" | "unset" | "static" | "absolute" | "fixed" | "sticky"'.
(property) search: {
    [x: string]: any;
    position: string;
}
Design Limitation

Most helpful comment

This is not specific to @ts-check as @aluanhaddad noted. you can find similar discussion in https://github.com/Microsoft/TypeScript/issues/16389.

The recommendation here is to add a type annotation on your declaration to guide the compiler to inferring the literal types, e.g.:

/** @type {{search: React.CSSProperties}} */
const styles = {
    search: {
        position: "relative",
    }
}

All 6 comments

This is just a case of the more general problem:

const x = { value: "lit" };
const y: { value: "lit" } = x; // Error

The problem is that since x has no type annotation, a new type is synthesized for it; and by default this type will use string instead of a string literal type.

This issue surfaces in TypeScript code as well and is unrelated to @ts-check.

The error stems from the fact that position is a mutable property of the styles local. because it is mutable, it is inferred as having type string instead of having a literal type.

See also #11465

This is not specific to @ts-check as @aluanhaddad noted. you can find similar discussion in https://github.com/Microsoft/TypeScript/issues/16389.

The recommendation here is to add a type annotation on your declaration to guide the compiler to inferring the literal types, e.g.:

/** @type {{search: React.CSSProperties}} */
const styles = {
    search: {
        position: "relative",
    }
}

Ah, great, should I keep this open or close it then?

There are a few of elk of #16389 around. we have no plans on changing the design at this point. we already had multiple iterations on how literal types are inferred and the current design seems to be the best compromise we can reach.

Sounds good. Closing!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manekinekko picture manekinekko  路  3Comments

wmaurer picture wmaurer  路  3Comments

seanzer picture seanzer  路  3Comments

blendsdk picture blendsdk  路  3Comments

weswigham picture weswigham  路  3Comments