vue-styled-components
vue-styled-components copied to clipboard
TypeScript Support?
Very much I wait for TS support. Is not enough for this Frankenstein - https://github.com/DiFuks/vue.tsx
I have no experience with TS, I've used only Flow type. If any of you are interested can submit a PR for this
Very basic type definitions. Add to a <name>.d.ts file in your project:
If you use tsx and have JSX.InstrinctElements defined somewhere you could swap HTMLElements for JSX.InstrinctElements.
declare module 'vue-styled-components' {
import * as CSS from 'csstype';
import * as Vue from 'vue';
export type CSSProperties = CSS.Properties<string | number>;
export type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject };
export interface CSSObject extends CSSProperties, CSSPseudos {
[ key: string ]: CSSObject | string | number | undefined;
}
export type CSS = CSSProperties;
export type StyledComponent = Vue.Component & Vue.VueConstructor & {
extend(cssRules: TemplateStringsArray, ...interpolate: TemplateStringsArray[]): StyledComponent
withComponent(target: Vue.VueConstructor): StyledComponent
}
export type StyledComponentElements<T=HTMLElements> = {
[k in keyof T]: (str: TemplateStringsArray) =>StyledComponent
}
export type Styled<T=HTMLElements> = StyledComponentElements & {
<T>(Component: T, props?:Record<string,Vue.PropOptions['type']>): (str: TemplateStringsArray) =>StyledComponent
}
export interface HTMLElements {
a: HTMLAnchorElement
abbr: HTMLElement
address: HTMLElement
area: HTMLAreaElement
article: HTMLElement
aside: HTMLElement
audio: HTMLAudioElement
b: HTMLElement
base: HTMLBaseElement
bdi: HTMLElement
bdo: HTMLElement
big: HTMLElement
blockquote: HTMLElement
body: HTMLBodyElement
br: HTMLBRElement
button: HTMLButtonElement
canvas: HTMLCanvasElement
caption: HTMLElement
cite: HTMLElement
code: HTMLElement
col: HTMLTableColElement
colgroup: HTMLTableColElement
data: HTMLElement
datalist: HTMLDataListElement
dd: HTMLElement
del: HTMLElement
details: HTMLElement
dfn: HTMLElement
dialog: HTMLDialogElement
div: HTMLDivElement
dl: HTMLDListElement
dt: HTMLElement
em: HTMLElement
embed: HTMLEmbedElement
fieldset: HTMLFieldSetElement
figcaption: HTMLElement
figure: HTMLElement
footer: HTMLElement
form: HTMLFormElement
h1: HTMLHeadingElement
h2: HTMLHeadingElement
h3: HTMLHeadingElement
h4: HTMLHeadingElement
h5: HTMLHeadingElement
h6: HTMLHeadingElement
head: HTMLElement
header: HTMLElement
hgroup: HTMLElement
hr: HTMLHRElement
html: HTMLHtmlElement
i: HTMLElement
iframe: HTMLIFrameElement
img: HTMLImageElement
input: HTMLInputElement
ins: HTMLModElement
kbd: HTMLElement
keygen: HTMLElement
label: HTMLLabelElement
legend: HTMLLegendElement
li: HTMLLIElement
link: HTMLLinkElement
main: HTMLElement
map: HTMLMapElement
mark: HTMLElement
menu: HTMLElement
menuitem: HTMLElement
meta: HTMLMetaElement
meter: HTMLElement
nav: HTMLElement
noscript: HTMLElement
object: HTMLObjectElement
ol: HTMLOListElement
optgroup: HTMLOptGroupElement
option: HTMLOptionElement
output: HTMLElement
p: HTMLParagraphElement
param: HTMLParamElement
picture: HTMLElement
pre: HTMLPreElement
progress: HTMLProgressElement
q: HTMLQuoteElement
rp: HTMLElement
rt: HTMLElement
ruby: HTMLElement
s: HTMLElement
samp: HTMLElement
script: HTMLScriptElement
section: HTMLElement
select: HTMLSelectElement
small: HTMLElement
source: HTMLSourceElement
span: HTMLSpanElement
strong: HTMLElement
style: HTMLStyleElement
sub: HTMLElement
summary: HTMLElement
sup: HTMLElement
table: HTMLTableElement
tbody: HTMLTableSectionElement
td: HTMLTableDataCellElement
textarea: HTMLTextAreaElement
tfoot: HTMLTableSectionElement
th: HTMLTableHeaderCellElement
thead: HTMLTableSectionElement
time: HTMLElement
title: HTMLTitleElement
tr: HTMLTableRowElement
track: HTMLTrackElement
u: HTMLElement
ul: HTMLUListElement
var: HTMLElement
video: HTMLVideoElement
wbr: HTMLElement
}
export let styled: Styled;
export default styled;
}
maybe this declaration is more then better.
declare module 'vue-styled-components' {
import * as CSS from 'csstype';
import * as Vue from 'vue';
export type CSSProperties = CSS.Properties<string | number>;
export type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject };
export interface CSSObject extends CSSProperties, CSSPseudos {
[key: string]: CSSObject | string | number | undefined;
}
export type CSS = CSSProperties;
type VueProps = {
[propsName: string]: {
type: new (...args: any[]) => unknown
default?: unknown
required?: boolean
validator?(value: unknown): boolean;
}
} | {
[propsName: string]: new (...args: any[]) => unknown
}
type PropsType<Props extends VueProps> = {
[K in keyof Props]:
Props[K] extends { type: new (...args: any[]) => unknown } ?
InstanceType<Props[K]['type']>
: Props[K] extends new (...args: any[]) => unknown ?
InstanceType<Props[K]>
: never
}
export type StyledComponent<Props extends VueProps> = Vue.Component & Vue.VueConstructor & {
extend<U extends VueProps>(cssRules: TemplateStringsArray, ...interpolate: TemplateStringsArray[]): StyledComponent<Props & U>
withComponent<V extends VueProps>(target: Vue.VueConstructor): StyledComponent<Props & V>
} & { new(props: PropsType<Props>): Vue.Component }
export type StyledComponentElements<T = HTMLElements> = {
[k in keyof T]: (str: TemplateStringsArray) => StyledComponent<{}>
}
export type Component = HTMLElements | keyof HTMLElements | Vue.Component | Vue.VueConstructor
export type Styled = StyledComponentElements & {
<T extends Component, Props extends VueProps>(Component: T, props?: Props): (str: TemplateStringsArray, ...placeholders: ((props: PropsType<Props>) => string | String | { toString: () => string | String })[]) => StyledComponent<Props>
}
export interface HTMLElements {
a: HTMLAnchorElement
abbr: HTMLElement
address: HTMLElement
area: HTMLAreaElement
article: HTMLElement
aside: HTMLElement
audio: HTMLAudioElement
b: HTMLElement
base: HTMLBaseElement
bdi: HTMLElement
bdo: HTMLElement
big: HTMLElement
blockquote: HTMLElement
body: HTMLBodyElement
br: HTMLBRElement
button: HTMLButtonElement
canvas: HTMLCanvasElement
caption: HTMLElement
cite: HTMLElement
code: HTMLElement
col: HTMLTableColElement
colgroup: HTMLTableColElement
data: HTMLElement
datalist: HTMLDataListElement
dd: HTMLElement
del: HTMLElement
details: HTMLElement
dfn: HTMLElement
dialog: HTMLDialogElement
div: HTMLDivElement
dl: HTMLDListElement
dt: HTMLElement
em: HTMLElement
embed: HTMLEmbedElement
fieldset: HTMLFieldSetElement
figcaption: HTMLElement
figure: HTMLElement
footer: HTMLElement
form: HTMLFormElement
h1: HTMLHeadingElement
h2: HTMLHeadingElement
h3: HTMLHeadingElement
h4: HTMLHeadingElement
h5: HTMLHeadingElement
h6: HTMLHeadingElement
head: HTMLElement
header: HTMLElement
hgroup: HTMLElement
hr: HTMLHRElement
html: HTMLHtmlElement
i: HTMLElement
iframe: HTMLIFrameElement
img: HTMLImageElement
input: HTMLInputElement
ins: HTMLModElement
kbd: HTMLElement
keygen: HTMLElement
label: HTMLLabelElement
legend: HTMLLegendElement
li: HTMLLIElement
link: HTMLLinkElement
main: HTMLElement
map: HTMLMapElement
mark: HTMLElement
menu: HTMLElement
menuitem: HTMLElement
meta: HTMLMetaElement
meter: HTMLElement
nav: HTMLElement
noscript: HTMLElement
object: HTMLObjectElement
ol: HTMLOListElement
optgroup: HTMLOptGroupElement
option: HTMLOptionElement
output: HTMLElement
p: HTMLParagraphElement
param: HTMLParamElement
picture: HTMLElement
pre: HTMLPreElement
progress: HTMLProgressElement
q: HTMLQuoteElement
rp: HTMLElement
rt: HTMLElement
ruby: HTMLElement
s: HTMLElement
samp: HTMLElement
script: HTMLScriptElement
section: HTMLElement
select: HTMLSelectElement
small: HTMLElement
source: HTMLSourceElement
span: HTMLSpanElement
strong: HTMLElement
style: HTMLStyleElement
sub: HTMLElement
summary: HTMLElement
sup: HTMLElement
table: HTMLTableElement
tbody: HTMLTableSectionElement
td: HTMLTableDataCellElement
textarea: HTMLTextAreaElement
tfoot: HTMLTableSectionElement
th: HTMLTableHeaderCellElement
thead: HTMLTableSectionElement
time: HTMLElement
title: HTMLTitleElement
tr: HTMLTableRowElement
track: HTMLTrackElement
u: HTMLElement
ul: HTMLUListElement
var: HTMLElement
video: HTMLVideoElement
wbr: HTMLElement
}
export let styled: Styled;
export default styled;
}
Any updates on this? It's been a couple months..
any news?
too type safe with @vue/composition-api
declare module "vue-styled-components" {
import * as CSS from "csstype"
import * as Vue from "vue"
import { defineComponent, ExtractPropTypes } from "@vue/composition-api"
type ExcludeArrayString<T> = T extends string[] ? never : T
type VueProps = ExcludeArrayString<Parameters<typeof defineComponent>[0]["props"]>
export type CSSProperties = CSS.Properties<string | number>
export type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject }
export interface CSSObject extends CSSProperties, CSSPseudos {
[key: string]: CSSObject | string | number | undefined
}
export type CSS = CSSProperties
export type StyledComponent<Props extends VueProps> = Vue.Component &
Vue.VueConstructor & {
extend<U extends VueProps>(
cssRules: TemplateStringsArray,
...interpolate: TemplateStringsArray[]
): StyledComponent<Props & U>
withComponent<V extends VueProps>(target: Vue.VueConstructor): StyledComponent<Props & V>
} & { new (props: ExtractPropTypes<Props>): Vue.Component }
export type StyledComponentElements = {
[k in keyof HTMLElementTagNameMap]: (str: TemplateStringsArray) => StyledComponent<{}>
}
export type Component = HTMLElementTagNameMap | keyof HTMLElementTagNameMap | Vue.Component | Vue.VueConstructor
export type Styled = StyledComponentElements & {
<T extends Component, Props extends VueProps>(Component: T, props?: Props): (
str: TemplateStringsArray,
...placeholders: ((props: ExtractPropTypes<Props>) => string | String | { toString: () => string | String })[]
) => StyledComponent<Props>
}
export let styled: Styled
export default styled
}
https://gist.github.com/katsuyaU/e371399f411baba78dc9a43d3303e995
example
import { PropType } from "@vue/composition-api"
import styled from "vue-styled-components"
interface Hoge {
fuga: number
}
styled("a", {
requiredProp: { type: String, required: true },
optionalProp: { type: String },
objectProp: { type: Object as PropType<Hoge> },
})`
height: ${props => props.requiredProp}px;
`
A problem arises injectglobal type How to solve it?
What about typing literal strings ? ex:
type MyCompProps = { value: 'value1' | 'value2'; }