Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在TypeScript中强制赋值?_Typescript - Fatal编程技术网

在TypeScript中强制赋值?

在TypeScript中强制赋值?,typescript,Typescript,例如,我想要一个函数,它接受一个数字对象,并用它的字符串化值替换每个数字。在JavaScript中,我可以编写如下内容: function myStringifier(object) { for (let key in object) { object[key] = object[key].toString(); } } myObject = { a: 1, b: 2, c: 3 }; myStringifier(myObject); 但是我如何在TypeScr

例如,我想要一个函数,它接受一个数字对象,并用它的字符串化值替换每个数字。在JavaScript中,我可以编写如下内容:

function myStringifier(object) {
  for (let key in object) {
    object[key] = object[key].toString();
  }
}

myObject = {
  a: 1,
  b: 2,
  c: 3
};

myStringifier(myObject);
但是我如何在TypeScript中处理这个问题呢?以下代码将产生错误:

function myStringifier(object : {[index: string]: number}) : void {
  for (let key in object) {
    object[key] = object[key].toString(); /* ERROR! Object properties are of type number 
    and therefore cannot be assigned any string values to */
  }
}
重要提示:我希望这样做,而不在函数范围内分配任何附加变量和/或复制对象或对其的引用

p.S.:将对象参数的类型设置为:

{[index: string]: number | string}
-也不是出路。我想确定传递的参数是一个数字对象

p.p.S.:

谢谢你的回答

我理解需求可能看起来有点关联,所以我可能应该提供真实的案例,而不是抽象的示例

我有一个函数,它接受几个参数,其中一个是附加参数的对象:

function setCookie(name, value, {path, domain, expires}) {...}
参数expires的值类型为Date,因此该函数的JavaScript实现可以将options对象上的这一字段转换为UTCString,然后只需获取整个options对象,解析它并附加到cookie字符串中

除了一个字段可以使用之外,选项对象,因此为它分配另一个变量只是为了满足TypeScript的要求似乎有点烦人

看起来有三条出路,但每一条都有自己的局限性:

  • “肮脏的黑客”风格
  • 第一种方法是使用类型转换:

    type cookieOptions = {
      domain?: string, 
      path? : string,
      expires?: Date
    };
    
    function setCookie(name : string, value : string, options : cookieOptions) {
       if ("expires" in options) {
         options.expires = options.expires.toUTCString() as any;  // type casting
       }
       for (let propName in options) {
         updatedCookie += `; ${propName}=${options[propName] as any}`; // type casting
       }
    }
    
    首先,这种担心迫使我们使用类型转换两次(将属性设置为格式化值和解析options对象时),其次,它违反了类型安全原则,这破坏了使用TypeScript的所有好处

  • “好的,我来处理”的风格
  • 我们可以只接受格式化字符串作为“expires”参数的可能值。但这意味着我们还必须改变实施方式

    type ExtendedCookieOptions = {
      domain?: string, 
      path? : string,
      expires?: string | Date
    };
    
    function setCookie(name : string, value : string, options : ExtendedCookieOptions) {...}
    
  • “好的,让我们分配一个变量并使用它”的风格由描述

    函数setCookie(名称:string,值:string,选项:cookieOptions){ 让params:{[index:string]:string}=options as any;//之后,我们忘记了“options”变量,而是使用“params” }


  • 同样,这里我们必须执行一个在JavaScript中似乎毫无用处的操作,只是为了满足TypeScript的要求,这就是为什么我不想添加变量,但在这种情况下,这似乎是最好的解决方法。

    您可以在分配中执行强制转换:

    function myStringifier(object: { [index: string]: number}): void {
      for (let key in object) {
        object[key] = object[key].toString() as any; // Cast to any here.
      }
    }
    

    这不需要任何额外的变量。

    您可以使用类型
    [index:string]:number | string
    (正如Louis之前所建议的),但这也意味着您可以在对象中混合数字和类型,而您可能希望不混合其中一个或另一个

    function myStringifier(object: {[index: string]: number}): {[index: string]: string} {
      let result: {[index: string]: string} = <any> object;
      for (let key in object) {
        result[key] = object[key].toString();
      }
      return result;
    }
    
    下面是如何在不分配其他变量的情况下实现额外的类型安全性

    function myStringifier(object: {[index: string]: number}): {[index: string]: string} {
      let result: {[index: string]: string} = <any> object;
      for (let key in object) {
        result[key] = object[key].toString();
      }
      return result;
    }
    
    函数mystringhier(对象:{[index:string]:number}):{[index:string]:string}{
    让结果:{[index:string]:string}=object;
    for(让输入对象){
    结果[key]=对象[key].toString();
    }
    返回结果;
    }
    
    要清楚的是,
    result
    不是一个“已分配”的附加变量,因为
    result
    将在堆栈上结束,堆栈是预先分配的内存

    注意:将对象参数的类型设置为:

    {[index: string]: number | string}
    
    {[索引:字符串]:数字|字符串} -也不是出路。我想确定传递的参数是一个数字对象

    如果您立即将同一个对象变为字符串对象,则传递的对象不是数字对象。它是数字或字符串的对象。这是一个错误的地方来强制您的对象具有数字键-您应该在最初创建对象时这样做


    值得一提的是,我键入变量的方式如下:
    {[index:string]:number}{[index:string]:string}
    。现在您知道它要么是all
    number
    s,要么是all
    string
    s

    我更喜欢你之前的答案,因为这样你得到一个TypeScript认为有数字但实际上有字符串的对象,这只是另一种打中你自己脚的方式。OP编辑了这个问题,明确拒绝了我最初的解决方案。鉴于OP的要求,必须以使TypeScript类型声明成为谎言的方式修改原始对象。您的解决方案的优点是提供了反映新类型的返回值,但它违背了OP的要求,即不存在其他变量。我想得越多,我就越觉得需求是任意的。我的解决方案没有额外的变量<代码>结果是指向堆栈上对象的指针。虽然在某些js框架中,改变对象而不是生成新对象是一项特殊要求,但该要求听起来确实是任意的。@LodewijkBogaards您的解决方案确实有一个附加变量<代码>结果是一个附加变量。它是否保存在堆栈中并不重要:它仍然是一个变量。不管它是否是指针:它仍然是一个变量。您的上一个要求违反了类型安全:函数返回后,此函数的调用方仍将对象类型为
    {[index:string]:number}
    ,这是错误的,因为值实际上是字符串。(没有办法说函数参数的类型在调用函数后发生了变化。)虽然类型可能更具信息性,但这并不比实际上只对对象的项使用
    number | string
    要好多少,因为如果从该函数中取消引用项