admin管理员组

文章数量:1279118

I am trying to convert some JS I found here into Typescript

Part of the problem is this bit of code

// Extract CSS Rules
    var extractedCSSText = "";
    for (var i = 0; i < document.styleSheets.length; i++) {
        var s = document.styleSheets[i];

        try {
            if(!s.cssRules) continue;
        } catch( e ) {
                if(e.name !== 'SecurityError') throw e; // for Firefox
                continue;
            }

        var cssRules = s.cssRules;
        for (var r = 0; r < cssRules.length; r++) {
            if ( contains( cssRules[r].selectorText, selectorTextArr ) )
                extractedCSSText += cssRules[r].cssText;
        }
    }

Which I tried to convert to Typescript this way:

// Extract CSS Rules
let extractedCSSText = '';
for (let i = 0; i < document.styleSheets.length; i++) {
    const s = <CSSStyleSheet> document.styleSheets[i];

    try {
        if (!s.cssRules) {
            continue;
        }
    } catch (e) {
        if (e.name !== 'SecurityError') {
            throw e; // for Firefox
        }
        continue;

    }

    const cssRules = s.cssRules;
    for (let r = 0; r < cssRules.length; r++) {
        if (contains(cssRules[r].selectorText, selectorTextArr)) {
            extractedCSSText += cssRules[r].cssText;
        }
    }
}

The error I receive is

Property 'selectorText' does not exist on type 'CSSRule'.

Not sure how to fix that one. Anyone any ideas please?

Thanks, Uwe

I am trying to convert some JS I found here into Typescript

http://bl.ocks/Rokotyan/0556f8facbaf344507cdc45dc3622177

Part of the problem is this bit of code

// Extract CSS Rules
    var extractedCSSText = "";
    for (var i = 0; i < document.styleSheets.length; i++) {
        var s = document.styleSheets[i];

        try {
            if(!s.cssRules) continue;
        } catch( e ) {
                if(e.name !== 'SecurityError') throw e; // for Firefox
                continue;
            }

        var cssRules = s.cssRules;
        for (var r = 0; r < cssRules.length; r++) {
            if ( contains( cssRules[r].selectorText, selectorTextArr ) )
                extractedCSSText += cssRules[r].cssText;
        }
    }

Which I tried to convert to Typescript this way:

// Extract CSS Rules
let extractedCSSText = '';
for (let i = 0; i < document.styleSheets.length; i++) {
    const s = <CSSStyleSheet> document.styleSheets[i];

    try {
        if (!s.cssRules) {
            continue;
        }
    } catch (e) {
        if (e.name !== 'SecurityError') {
            throw e; // for Firefox
        }
        continue;

    }

    const cssRules = s.cssRules;
    for (let r = 0; r < cssRules.length; r++) {
        if (contains(cssRules[r].selectorText, selectorTextArr)) {
            extractedCSSText += cssRules[r].cssText;
        }
    }
}

The error I receive is

Property 'selectorText' does not exist on type 'CSSRule'.

Not sure how to fix that one. Anyone any ideas please?

Thanks, Uwe

Share Improve this question asked Jan 25, 2018 at 20:34 UweUwe 5157 silver badges20 bronze badges 1
  • since CSSRule is not a type written by yourself you can't really avoid this. A quite bad solution would be smth like this: if (contains((cssRules[r] as any).selectorText, selectorTextArr)) {... – messerbill Commented Jan 25, 2018 at 20:42
Add a ment  | 

3 Answers 3

Reset to default 8

The problem is that the CSS spec was defined so that not all rules are necessarily styles.

You have to make sure that the CSSRule is a CSSStyleRule (as there can be different types of CSS rules that are not styles). It can also be an import rule, keyframe rule, media rule, etc.

Think about a keyframe rule, keyframes don't have selectors so you won't have selectorText property on that rule. So, the error is TypeScript doing what it is supposed to do. Make sure you don't access invalid properties.

Try paring the CSStyleRule properties and CSSMediaRule properties. They are different.

Try this:

 const cssRules = s.cssRules;
 for (let r = 0; r < cssRules.length; r++) {
    const rule = cssRules[r];
    if (!( rule instanceof CSSStyleRule)) {
        continue;
    }
    if (contains(rule.selectorText, selectorTextArr)) {
        extractedCSSText += rule.cssText;
    }
}

Here is an example where simply casting would result in an error being thrown later as selectorText can be undefined: https://codepen.io/anon/pen/EoBJeM (see console). Avoid casting whenever possible.

It's a little hard to debug without more context and a working code example, but I believe you just need to change the assignment on line 4 to be:

const s: CSSStyleSheet = document.styleSheets[i];

so far you have no access to the definitions of the CSSRule type you can not really avoid it. To get rid of the error try smth like:

if (contains((cssRules[r] as any).selectorText, selectorTextArr)) {...

according to Cristys ments this may also work (if it works, use this one):

if (contains((cssRules[r] as CSSStyleRule).selectorText, selectorTextArr)) {...

Note: You should always try NOT to use the any type, but i guess it is ok in this case.

本文标签: