css-blocks icon indicating copy to clipboard operation
css-blocks copied to clipboard

TypeScript type checking for css-blocks as imported modules.

Open chriseppstein opened this issue 8 years ago • 1 comments

Each CSS block file can be represented as a collection of TypeScript classes.

.root { block-name: a-css-block; }
[state|a-block-state] {}
.a-thing {}
.a-thing[state|active] {}
.a-thing[state|my-theme=red] {}
.a-thing[state|my-theme=blue] {}
// these would be defined statically for all blocks and imported
type OptimizedClassNames = string[];
export interface BlockClass {
}
export type BooleanBlockState = () => OptimizedClassNames;
export type ExclusiveBlockState = (value: string) => OptimizedClassNames;
export type BlockState = BooleanBlockState | ExclusiveBlockState;
// type for this block
export class ACssBlock implements BlockClass {
  root: this;
  active: () => OptimizedClassNames;
  "a-thing": ACssBlock.AThingClass;
  [name: string]: BlockClass | BlockState;
}
export namespace ACssBlock {
   export class AThingClass implements BlockClass {
    [name: string]: BlockState;
     "my-theme": (value: "red" | "blue") => OptimizedClassNames;
   }
}
// usage example:
function foo(a: ACssBlock): OptimizedClassNames {
  return a["a-thing"]["my-theme"]("red");
}

TODO:

  • [ ] Further examples of block interfaces and inheritance are needed.
  • [ ] Figure out how to create indexed types with only a limited set of indexed names.

chriseppstein avatar Jul 30 '17 17:07 chriseppstein

Just swinging by many years down the line with a hint on how some of the type issues can be solved:

type MyBlockNameMap = {
    readonly [K in 'foo' | 'bar']: readonly string[];
}

type MyBlockFunctions = {
    color(name: 'red' | 'blue'): readonly string[];
}

type MyBlock = MyBlockNameMap & MyBlockFunctions;

let styles: MyBlock = null as any;
let bar: readonly string[] = styles.bar;
let foo: readonly string[] = styles.foo;
let red: readonly string[] = styles.color('red');
let blue: readonly string[] = styles.color('blue');

Alxandr avatar May 07 '20 14:05 Alxandr