【问题标题】:Infer string literal type from a JSON file从 JSON 文件推断字符串文字类型
【发布时间】:2021-10-14 06:06:17
【问题描述】:

我正在读取一个大型 JSON 文件。
TypeScript 足够聪明,可以推断所有属性的类型除了一个

一个简化的例子:

type Animal = 'bear' | 'cat' | 'dog';

const data = {
  name: 'Max',
  age: 3,
  animal: 'dog',
  // 100s other properties from JSON file...
};

let theName: string = data.name; // perfect
let theAge: number = data.age; // perfect
let theAnimal: Animal = data.animal; // Error: Type 'string' is not assignable to type 'Animal'

(link to playground)

data.animal 用于多个地方,所以我尽量避免在任何地方使用as Animal

解决此问题的最佳方法是什么?
有什么简单的方法可以告诉代码data.animalAnimal

【问题讨论】:

    标签: typescript string-literals


    【解决方案1】:

    您可以使用求和类型并合并 2 个定义 - 数据的原始定义和动物:动物定义。

    type Animal = 'bear' | 'cat' | 'dog';
    
    // the keys your want to exert
    type DataWithAnimal = { [P in 'animal']: Animal } ;
    
    const data = {
      name: 'Max',
      age: 3,
      animal: 'dog',
      // 100s other properties from JSON file...
    };
    
    // original data type
    type DataType = typeof data;
    
    // merge the 2 type definitions
    type Data = DataType & DataWithAnimal;
    
    // cast old type to new type
    const typeData: Data = data as Data;
    
    let theName: string = typeData.name; // perfect
    let theAge: number = typeData.age; // perfect
    let theAnimal: Animal = typeData.animal; // also perfect
    
    

    【讨论】:

    • 完美!谢谢@kirin nee!!您介意解释一下[P in 'animal'] 位吗?
    【解决方案2】:

    这样怎么样?

    type Animal = 'bear' | 'cat' | 'dog';
    
    type Data = {
      name: string;
      age: number;
      animal: Animal;
    }
    const data: Data = {
      name: 'Max',
      age: 3,
      animal: 'dog',
      // 100s other properties from JSON file...
    };
    
    let theName: string = data.name; // perfect
    let theAge: number = data.age; // perfect
    let theAnimal: Animal = data.animal;
    

    【讨论】:

    • 嗯...谢谢,但我们在这里讨论的是一个 339 行的 JSON 文件...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 2020-12-22
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2019-06-26
    • 2021-06-16
    相关资源
    最近更新 更多