TypeScript:标记模板文字显示错误

时间:2017-02-28 06:38:55

标签: javascript typescript template-literals

我正在尝试使用ES5的tagged template literal和打字稿,但似乎类型脚本没有完全支持它。我有以下一段代码。

class TemplateLiterals { 
    age: number = 24;
    name: 'Luke Skywalker'
    private tag(strings: string[], personExp, ageExp) :string{
        var str0 = strings[0]; // "that "
        var str1 = strings[1]; // " is a "
        var ageStr;
        if (ageExp > 99) {
            ageStr = 'centenarian';
        } else {
            ageStr = 'youngster';
        }
        return str0 + personExp + str1 + ageStr;
    }
    toString() {
        return this.tag `that ${ this.name } is a ${ this.age }`;
    }
}

toString方法中,typescript显示以下错误。

Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'string[]'.
Property 'push' is missing in type 'TemplateStringsArray'.

我不知道为什么它会向我显示此错误。根据mozilla的doc"标记函数的第一个参数包含一个字符串值数组。"所以它应该接受字符串数组。但实际预期是TemplateStringsArray。不确定定义interface TemplateSringsArray的方式和时间。目前我使用TemplateSringsArray类型来避免此错误。任何人都可以解释发生了什么。谢谢。这是playground

2 个答案:

答案 0 :(得分:9)

经过深入探索,我终于在change log找到了解释。希望它会帮助某人。它说

  

ES2015标记模板总是将其标记传递给不可变的数组   具有称为raw的属性的对象(也是不可变的)。   TypeScript将此对象命名为TemplateStringsArray。

     

方便的是,TemplateStringsArray可以赋值给Array,   因此,用户可以利用这一点来使用更短的类型   对于他们的标签参数:

import React, { Component } from 'react';
import { Link } from 'react-router'
import { Dropdown, DropdownMenu, DropdownItem, Progress } from 'reactstrap';

class Notifications extends Component {
  constructor(){
    super();
    this.state = {
            data:[
                {title:"Nikko Laus1" , text:"abcd" , type:"Big text" },
                {title:"Sam Collins", text:"" ,type:"Inbox style"},
                {title:"Sam ", text:"" ,type:"Image style"}   
            ]
        };
  }

  render() {
    let rows = this.state.data.map(person =>
        {
            return <TableRow key={person.id} data={person}/>
        });
    return (<div><div>
          <div className="animated fadeIn">
           <div className="px-2 mb-1">
                <Link to={'/Components/BasicNotification'} style= {{ width:20 + '%' }} className="nav-link btn btn-block btn-success" activeClassName="active">Add Notification</Link>

                  </div>

            <br /><div className="card" style={{ width: 57 + '%' }}>
              <div className="card-header">
                 Manage Notifications
              </div>
              <div className="card-block">
               

      <table  className="table table-hover table-outline mb-0 hidden-sm-down">
        
                <tbody>
                {this.props.type.Bigtext ? <Link to={'/Components/BigText'} className="nav-link" activeClassName="active" />:
                this.props.type.ImageStyle ? <Link to={'/Components/ImageStyle'} className="nav-link" activeClassName="active" />:
                <Link to={'/Components/InboxStyle'}   className="nav-link" activeClassName="active" />}
                 {rows}</tbody>
            </table></div>

               
<br />

            </div>
          </div><div className="px-2 mb-1"><Link to={'/components/tabs'} style={{ width:20 + '%' }} className="px-1 nav-link btn btn-block btn-success" activeClassName="active">Filter Notifications</Link>
</div>
</div></div>
      
      
        
      
    )
  }
}

class TableRow extends React.Component
{
    constructor()
    {
        super();
    }

    render()
    {
        return (<tr>
                    <td className="text-center">{this.props.data.title}<br />
                    {this.props.data.text}<br /></td></tr>
      
            );
    }
}


export default Notifications;
  

但是,在TypeScript 2.0中,该语言现在支持readonly修饰符和   可以表示这些对象是不可变的。如   结果,TemplateStringsArray也变得不可变,并且没有   更长的可分配给字符串[]。

建议:

明确使用function myTemplateTag(strs: string[]) { // ... } (或使用TemplateStringsArray)。

答案 1 :(得分:1)

我也找不到关于TemplateStringsArray的任何文档 - 但是如果您只是通过将参数更改为TemplateStringsArray而不是string[]来忽略错误(并修复名称成员的错误) )它似乎工作正常

class TemplateLiterals { 
    age: number = 24;
    name: string = 'Luke Skywalker'
    private tag(strings: TemplateStringsArray, personExp, ageExp) :string{
        var str0 = strings[0]; // "that "
        var str1 = strings[1]; // " is a "
        var ageStr;
        if (ageExp > 99) {
            ageStr = 'centenarian';
        } else {
            ageStr = 'youngster';
        }
        return str0 + personExp + str1 + ageStr;
    }
    toString() {
        return this.tag `that ${ this.name } is a ${ this.age }`;
    }
}

var luke: TemplateLiterals = new TemplateLiterals()
console.log(luke.toString())