例如,我想要一个带有数字对象的函数,并用字符串化的值替换每个数字。在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实现只能在选项上转换此字段将对象转换为UTCString,然后只取整个选项对象,解析它并附加到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
}
}
首先,这个问题迫使我们使用类型转换两次(同时将属性设置为格式化的值并解析选项对象),其次,它违反了类型安全的原则,它破坏了使用的所有好处打字稿。
我们可以接受格式化的字符串作为“expires”参数的可能值。但这意味着我们还必须改变实施。
type ExtendedCookieOptions = {
domain?: string,
path? : string,
expires?: string | Date
};
function setCookie(name : string, value : string, options : ExtendedCookieOptions) {...}
“好的,我们分配一个变量并使用它”Lodewijk描述的样式。
function setCookie(name:string,value:string,options:cookieOptions){ 让params:{[index:string]:string} = options as any; //之后,我们忘记了“options”变量并改为使用“params” }
同样,在这里我们必须执行一个在JavaScript中看起来绝对无用的操作,只是为了满足TypeScript的要求,并且s why I didn
想要添加变量,但在这种情况下它似乎是最好的出路。
答案 0 :(得分:0)
您可以在作业中执行演员表:
function myStringifier(object: { [index: string]: number}): void {
for (let key in object) {
object[key] = object[key].toString() as any; // Cast to any here.
}
}
这不需要任何其他变量。
答案 1 :(得分:0)
您可以使用类型[index: string]: number | string
(如之前路易斯建议的那样),但这也意味着您可以在对象中混合使用数字和类型,而您可能希望在不混合的情况下使用其中一种或另一种。
以下是如何在不分配其他变量的情况下实现额外的类型安全性。
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;
}
要清楚result
不是&#34;已分配&#34;的附加变量,因为result
将在堆栈上结束,这是预先分配的内存。
答案 2 :(得分:0)
P.S。:将对象参数的类型设置为:
{[index:string]:number |串} - 也不是出路。我想确保传递的参数是一个数字对象。
如果您立即将同一个对象变为字符串对象,那么您传入的对象不是数字对象。它是数字或字符串的对象。这是强制您的对象具有数字键的错误位置 - 您最初创建对象时应该这样做。
对于它的价值,我输入变量的方式如下:{ [index: string]: number } | { [index: string]: string }
。现在您知道所有number
s或全部string
s。