我的函数没有返回正确的类型,可以吗?

时间:2019-02-08 09:40:53

标签: typescript

我目前正在过滤带标签的枚举,但是我的函数未返回正确的类型。我不知道为什么

function fromNameLabels<T extends string>(src: Array<[T, string]>): 
Array<LabelledEnum<T>> {
    return src.map(([name, label]) => ({ name, label }))
}  

function fromLabelledEnum<T extends string>(src: 
Array<LabelledEnum<T>>): { [K in T]: K } {
    return src.reduce((res, {name, label}) => {
        res[name] = name
        return res
    }, Object.create(null))
}  

type Mandant = 'REN' | 'COVEA'
type TabEnum =  Array<LabelledEnum<string>>
type MapTabEnum = Record<Mandant,TabEnum>

function getTabEnumByMandant ( mandant: Mandant) {
    return TypeRendezVousValuesMap[mandant]
}

export const TypeRendezVousValuesREN = fromNameLabels([
    ["Site","Sur site"],
    ["Visio","En visio"],
    ["Telephonique","Par téléphone"],
    ["RdvGalant","Rendez vous galant"],
    ["RdvSport","rendez vous sportif"],
    ["MatchSquash","match de squash"],
])

export const TypeRendezVousValuesCOVEA = fromNameLabels([
    ["RdvGalant","Rendez vous galant"],
    ["RdvSport","rendez vous sportif"],
    ["MatchSquash","match de squash"],
])

export const TypeRendezVousValuesMap: MapTabEnum = {
    'REN':TypeRendezVousValuesREN,
    'COVEA':TypeRendezVousValuesCOVEA
}

export const TypeRendezVousCovea = fromLabelledEnum(getTabEnumByMandant ('COVEA'))
export type TypeRendezVous = keyof typeof TypeRendezVousCovea

我想要的是我的TypeRendezVousCovea这种类型的

const TypeReference: {
    ReferenceSinistre: "ReferenceSinistre";
    NumeroContrat: "NumeroContrat";
    Autre: "Autre";
}

但实际上是这种类型:

const TypeRendezVousCovea: {
    [x: string]: string;
}

有人有什么想法吗,或者有可能吗? 我正在使用3.0.1版的打字稿。

1 个答案:

答案 0 :(得分:2)

有一些导致问题的小问题。第一个是getTabEnumByMandant需要一个通用类型参数来捕获传递的实际值,以便返回TypeRendezVousValuesMap中键的确切类型。

此外,由于您明确键入了TypeRendezVousValuesMap,因此对象文字的实际类型也会丢失。如果我们删除注释,它将保留类型。如果您想约束TypeRendezVousValuesMap,则可以使用通用函数(如下所述)

type LabelledEnum<T> = { name: T, label: string }
function fromNameLabels<T extends string>(src: Array<[T, string]>): Array<LabelledEnum<T>> {
  return src.map(([name, label]) => ({ name, label }))
}

function fromLabelledEnum<T extends string>(src: Array<LabelledEnum<T>>): { [K in T]: K } {
  return src.reduce((res, { name, label }) => {
    res[name] = name
    return res
  }, Object.create(null))
}

type Mandant = 'REN' | 'COVEA'
type TabEnum = Array<LabelledEnum<string>>
type MapTabEnum = Record<Mandant, TabEnum>

function getTabEnumByMandant<K extends Mandant>(mandant: K) {
  return TypeRendezVousValuesMap[mandant]
}

export const TypeRendezVousValuesREN = fromNameLabels([
  ["Site", "Sur site"],
  ["Visio", "En visio"],
  ["Telephonique", "Par téléphone"],
  ["RdvGalant", "Rendez vous galant"],
  ["RdvSport", "rendez vous sportif"],
  ["MatchSquash", "match de squash"],
])

export const TypeRendezVousValuesCOVEA = fromNameLabels([
  ["RdvGalant", "Rendez vous galant"],
  ["RdvSport", "rendez vous sportif"],
  ["MatchSquash", "match de squash"],
])

export const TypeRendezVousValuesMap = (<T extends MapTabEnum>(o: T) => o)({
  'REN': TypeRendezVousValuesREN,
  'COVEA': TypeRendezVousValuesCOVEA
})

export const TypeRendezVousCovea = fromLabelledEnum(getTabEnumByMandant('COVEA'))
// const TypeRendezVousCovea: {
//   RdvGalant: "RdvGalant";
//   RdvSport: "RdvSport";
//   MatchSquash: "MatchSquash";
// }