Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS Selectors using hyphens aren't compile-time checked due to square bracket access #26

Open
silbinarywolf opened this issue Sep 30, 2019 · 5 comments

Comments

@silbinarywolf
Copy link

silbinarywolf commented Sep 30, 2019

Problem
I discovered when using this that if you write CSS selectors like this .my-selector, with a hyphen, when you import the CSS and access it with square bracket syntax, you lose compile-time checking on whether the selector / property exists or not.

.contact-details {
  color: #000;
}
.ContactDetails {
  color: #000;
}
// No compile-time error!
styles["contact-dAetails"]

// You get a compile-time error!
styles.ContactDAetails

Proposed solution(s)
a) Figure out if TypeScript has the ability to enforce checking when accessing something with square brackets.
b) If "a" is not possible, at least mention in documentation that this is a problem!

Notable TSConfig setup

  • noImplicitAny: false
@silbinarywolf silbinarywolf changed the title CSS Selectors using hyphens aren't type-checked due to square bracket access CSS Selectors using hyphens aren't compile-time checked due to square bracket access Sep 30, 2019
@silbinarywolf
Copy link
Author

silbinarywolf commented Sep 30, 2019

The following alternate generated syntax will give compile-time errors with hyphen values.

// This file is automatically generated.
// Please do not change this file!
const enum CssExports {
	'item' = 'item',
	'list' = 'list',
	'root' = 'root',
	'text' = 'text',
	'text--small' = 'text--small',
	'title' = 'title',
	'title--small' = 'title--small',
}
declare const cssExports: typeof CssExports;
export = cssExports;
[tsl] ERROR in C:\javascript\my-component.tsx(28,33)
      TS2339: Property 'titlae--small' does not exist on type 'typeof CssExports'.

Potential problems

@silbinarywolf
Copy link
Author

@jahredhope I'm happy to make a PR + tests if you guys are willing to accept it.
If I put in the effort will this get merged?

@silbinarywolf
Copy link
Author

I explored this option and it can fail in cases where users simply passed the entire styles variable to another value.

ie. we're utilizing this in a project using Aurelia (with an aim to move slowly to React), so for our Aurelia components, we can't expose the CSS modules object to the templater of that particular framework.

@autoinject
@useView(PLATFORM.moduleName('./my-component.html'))
export class MyComponent  {
	private readonly styles = styles;
}

I'm going to close this.

@silbinarywolf
Copy link
Author

silbinarywolf commented Oct 18, 2019

Nevermind, I think I have a nice solution / patch to this problem.
We just define an index signature that returns void.

For example:

// This file is automatically generated.
// Please do not change this file!
interface CssExports {
  [key: string]: void; // <- this makes typos give you an error
  'orb': string;
  'orb-active-user': string;
  'orb-exited-user': string;
  'orb-list': string;
}
declare const cssExports: CssExports;
export = cssExports;
ERROR in components\entity-search\entity-search.tsx
components/entity-search/entity-search.tsx
[tsl] ERROR in components\entity-search\entity-search.tsx(945,7)
      TS2322: Type 'void' is not assignable to type 'string'.

@silbinarywolf
Copy link
Author

silbinarywolf commented Oct 18, 2019

This approach has problems as pointed out by @MattsJones in his comment:
#29 (comment)

Needs further investigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant