Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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,在Typescript中,以下内容似乎可以完成所需类型的创建: interface RecordX extends Record<string, string[]> { id: string } 但每一个似乎都会导致错误 这感觉很普通,很明显,但我找不到一个例子或参考 如果未将其用于类,则可以使用类型对其进行描述: type RecordWithID = Record<string, string[]> & { id: string } let x:

在Typescript中,以下内容似乎可以完成所需类型的创建:

interface RecordX extends Record<string, string[]> {
  id: string
}
但每一个似乎都会导致错误

这感觉很普通,很明显,但我找不到一个例子或参考


如果未将其用于
,则可以使用
类型
对其进行描述:

type RecordWithID = Record<string, string[]> & {
  id: string
}

let x: RecordWithID = {} as any

x.id = 'abc'

x.abc = ['some-string']
键入RecordWithID=Record&{
id:字符串
}
设x:RecordWithID={}为任意
x、 id='abc'
x、 abc=['some-string']

从官方角度来看,你不可能实现你想要的:

而字符串索引签名是描述 “字典”模式,它们还强制所有属性匹配 它们的返回类型。这是因为字符串索引声明 obj.property也可以作为obj[“property”]提供。在下面 例如,名称的类型与字符串索引的类型不匹配,并且 类型检查器出现错误:

interface NumberDictionary {
    [index: string]: number;
    length: number;    // ok, length is a number
    name: string;      // error, the type of 'name' is not a subtype of the indexer
}
然而,根据这一点,从索引签名中排除某些属性在一种情况下是可能的:当您想要对声明的变量建模时。我正在从网站上复制整个部分

有时需要将属性组合到索引签名中。 不建议这样做,您应该使用嵌套索引签名 上面提到的模式。但是,如果您正在建模现有的 JavaScript您可以使用交叉点类型绕过它。这个 下面显示了一个您将遇到的错误示例 使用交叉点:

type FieldState = {
  value: string
}

type FormState = {
  isValid: boolean  // Error: Does not conform to the index signature
  [fieldName: string]: FieldState
}
以下是使用交叉点类型的解决方法:

type FieldState = {
  value: string
}

type FormState =
  { isValid: boolean }
  & { [fieldName: string]: FieldState }
请注意,即使您可以将其声明为现有JavaScript建模, 无法使用TypeScript创建此类对象:

type FieldState = {
  value: string
}

type FormState =
  { isValid: boolean }
  & { [fieldName: string]: FieldState }


// Use it for some JavaScript object you are gettting from somewhere 
declare const foo:FormState; 

const isValidBool = foo.isValid;
const somethingFieldState = foo['something'];

// Using it to create a TypeScript object will not work
const bar: FormState = { // Error `isValid` not assignable to `FieldState
  isValid: false
}
最后,作为一种变通方法,如果合适的话,您可以创建一个嵌套接口(请查看的“设计模式:嵌套索引签名”部分,其中动态字段位于接口的属性中

interface RecordX {
  id: string,
  count: number,
  set: Set<number>,
  dynamicFields: {
    [k: string]: string[]
  }
}
接口记录x{
id:string,
计数:数字,
集:集,,
动态字段:{
[k:string]:字符串[]
}
}

佩德罗的答案100%正确,是我旅程的开始,谢谢

我想找到最简单的解决方法,并找到了一个解决方案:
Object.assign()
。手动构造这些对象时,甚至在使用spread运算符时,可能作为带有本机JavaScript功能的TypeScript互操作,似乎都不会出现类型错误

Object.assign()
包装在工厂函数中并与并行类型相结合对我来说很优雅,也许它对其他人有用

//类型为的工厂
//工厂使用Object.assign(),它不会出错,并返回交叉点类型
函数RecordX(
fixedProps:{id:string},
动态操作?:记录
) {
返回Object.assign({},dynamicrops,fixedProps);
}
//类型名称方便地与工厂重叠,并解析为:
// 
//类型RecordX=记录&{
//id:字符串;
// }
类型RecordX=返回类型;
//用法
//标准使用
常量模型:RecordX=RecordX({id:'id-1'}{
foo:[a'],
});
//正确类型:string
const id=model.id;
//正确类型:字符串[]
const otherProp=model.otherProp;
//“字符串不可分配给字符串[]”的相应错误
常量model2:RecordX=RecordX({id:'id-2'}{
酒吧:“b”
});

Record
意味着
id
属性(如果存在)必须是
字符串[]
。您不能使用与之不匹配的内容对其进行扩展;您正在尝试创建一个异常,而不是扩展,并且TypeScript(尚未)没有作为一个具体的类型来支持它。如果您想知道如何做,您可能需要扩展您的用例。请确保您的代码是一个;现在与
记录的名称冲突模糊了您的问题。@jcalz添加了更多的描述+M原因是当遇到问题时,TypeScript试图做更多的事情o对象文字。这样做是为了避免明显的错误。因此,如果在对象文字构造之后添加动态属性,它将起作用。-我遇到了一些问题,因此我更新了问题的更多细节,并(希望暂时)将其取消标记为正确的解决方案。
type FieldState = {
  value: string
}

type FormState =
  { isValid: boolean }
  & { [fieldName: string]: FieldState }


// Use it for some JavaScript object you are gettting from somewhere 
declare const foo:FormState; 

const isValidBool = foo.isValid;
const somethingFieldState = foo['something'];

// Using it to create a TypeScript object will not work
const bar: FormState = { // Error `isValid` not assignable to `FieldState
  isValid: false
}
interface RecordX {
  id: string,
  count: number,
  set: Set<number>,
  dynamicFields: {
    [k: string]: string[]
  }
}