jsonresume / resume-schema

JSON-Schema is used here to define and validate our proposed resume json
http://jsonresume.org
MIT License
2.15k stars 277 forks source link

TypeScript support #327

Open Jack-Works opened 5 years ago

Jack-Works commented 5 years ago

Does JSON Resume have definition in .d.ts file?

evanplaice commented 4 years ago

I've been looking into this. My initial impression is that it should be easy to setup if this tool works as advertised.

aboodz commented 4 years ago

I tried using json-schema-to-typescript it didn't generate a quite useable definition file. The generator didn't generate a type for complex objects. The generator only generates a type if it's defined in definitions.

This is what is generated

export interface ResumeSchema {
  basics?: {
    name?: string;
    label?: string;
    // ..
    summary?: string;
    location?: {
      address?: string;
      // ...
      region?: string;
      [k: string]: any;
    };
  }
}

A usable one could be

export interface ResumeSchema {
  basics: BasicSchema;
  // ..
}
export interface BasicSchema {
  name?: string;
  // ..
  location?: LocationSchema
}
export interface LocationSchema {
  // ..
}
johnb8005 commented 4 years ago

what about (generated with: https://transform.tools/json-schema-to-typescript)

/**
 * e.g. 2014-06-29
 */
export type Iso8601 = string;

export interface ResumeSchema {
  /**
   * link to the version of the schema that can validate the resume
   */
  $schema?: string;
  basics?: {
    name?: string;
    /**
     * e.g. Web Developer
     */
    label?: string;
    /**
     * URL (as per RFC 3986) to a image in JPEG or PNG format
     */
    image?: string;
    /**
     * e.g. thomas@gmail.com
     */
    email?: string;
    /**
     * Phone numbers are stored as strings so use any format you like, e.g. 712-117-2923
     */
    phone?: string;
    /**
     * URL (as per RFC 3986) to your website, e.g. personal homepage
     */
    url?: string;
    /**
     * Write a short 2-3 sentence biography about yourself
     */
    summary?: string;
    location?: {
      /**
       * To add multiple address lines, use
       * . For example, 1234 Glücklichkeit Straße
       * Hinterhaus 5. Etage li.
       */
      address?: string;
      postalCode?: string;
      city?: string;
      /**
       * code as per ISO-3166-1 ALPHA-2, e.g. US, AU, IN
       */
      countryCode?: string;
      /**
       * The general region where you live. Can be a US state, or a province, for instance.
       */
      region?: string;
      [k: string]: unknown;
    };
    /**
     * Specify any number of social networks that you participate in
     */
    profiles?: {
      /**
       * e.g. Facebook or Twitter
       */
      network?: string;
      /**
       * e.g. neutralthoughts
       */
      username?: string;
      /**
       * e.g. http://twitter.example.com/neutralthoughts
       */
      url?: string;
      [k: string]: unknown;
    }[];
    [k: string]: unknown;
  };
  work?: {
    /**
     * e.g. Facebook
     */
    name?: string;
    /**
     * e.g. Menlo Park, CA
     */
    location?: string;
    /**
     * e.g. Social Media Company
     */
    description?: string;
    /**
     * e.g. Software Engineer
     */
    position?: string;
    /**
     * e.g. http://facebook.example.com
     */
    url?: string;
    startDate?: Iso8601;
    endDate?: Iso8601;
    /**
     * Give an overview of your responsibilities at the company
     */
    summary?: string;
    /**
     * Specify multiple accomplishments
     */
    highlights?: string[];
    [k: string]: unknown;
  }[];
  volunteer?: {
    /**
     * e.g. Facebook
     */
    organization?: string;
    /**
     * e.g. Software Engineer
     */
    position?: string;
    /**
     * e.g. http://facebook.example.com
     */
    url?: string;
    startDate?: Iso8601;
    endDate?: Iso8601;
    /**
     * Give an overview of your responsibilities at the company
     */
    summary?: string;
    /**
     * Specify accomplishments and achievements
     */
    highlights?: string[];
    [k: string]: unknown;
  }[];
  education?: {
    /**
     * e.g. Massachusetts Institute of Technology
     */
    institution?: string;
    /**
     * e.g. http://facebook.example.com
     */
    url?: string;
    /**
     * e.g. Arts
     */
    area?: string;
    /**
     * e.g. Bachelor
     */
    studyType?: string;
    startDate?: Iso8601;
    endDate?: Iso8601;
    /**
     * grade point average, e.g. 3.67/4.0
     */
    score?: string;
    /**
     * List notable courses/subjects
     */
    courses?: string[];
    [k: string]: unknown;
  }[];
  /**
   * Specify any awards you have received throughout your professional career
   */
  awards?: {
    /**
     * e.g. One of the 100 greatest minds of the century
     */
    title?: string;
    date?: Iso8601;
    /**
     * e.g. Time Magazine
     */
    awarder?: string;
    /**
     * e.g. Received for my work with Quantum Physics
     */
    summary?: string;
    [k: string]: unknown;
  }[];
  /**
   * Specify your publications through your career
   */
  publications?: {
    /**
     * e.g. The World Wide Web
     */
    name?: string;
    /**
     * e.g. IEEE, Computer Magazine
     */
    publisher?: string;
    releaseDate?: Iso8601;
    /**
     * e.g. http://www.computer.org.example.com/csdl/mags/co/1996/10/rx069-abs.html
     */
    url?: string;
    /**
     * Short summary of publication. e.g. Discussion of the World Wide Web, HTTP, HTML.
     */
    summary?: string;
    [k: string]: unknown;
  }[];
  /**
   * List out your professional skill-set
   */
  skills?: {
    /**
     * e.g. Web Development
     */
    name?: string;
    /**
     * e.g. Master
     */
    level?: string;
    /**
     * List some keywords pertaining to this skill
     */
    keywords?: string[];
    [k: string]: unknown;
  }[];
  /**
   * List any other languages you speak
   */
  languages?: {
    /**
     * e.g. English, Spanish
     */
    language?: string;
    /**
     * e.g. Fluent, Beginner
     */
    fluency?: string;
    [k: string]: unknown;
  }[];
  interests?: {
    /**
     * e.g. Philosophy
     */
    name?: string;
    keywords?: string[];
    [k: string]: unknown;
  }[];
  /**
   * List references you have received
   */
  references?: {
    /**
     * e.g. Timothy Cook
     */
    name?: string;
    /**
     * e.g. Joe blogs was a great employee, who turned up to work at least once a week. He exceeded my expectations when it came to doing nothing.
     */
    reference?: string;
    [k: string]: unknown;
  }[];
  /**
   * Specify career projects
   */
  projects?: {
    /**
     * e.g. The World Wide Web
     */
    name?: string;
    /**
     * Short summary of project. e.g. Collated works of 2017.
     */
    description?: string;
    /**
     * Specify multiple features
     */
    highlights?: string[];
    /**
     * Specify special elements involved
     */
    keywords?: string[];
    startDate?: Iso8601;
    endDate?: Iso8601;
    /**
     * e.g. http://www.computer.org/csdl/mags/co/1996/10/rx069-abs.html
     */
    url?: string;
    /**
     * Specify your role on this project or in company
     */
    roles?: string[];
    /**
     * Specify the relevant company/entity affiliations e.g. 'greenpeace', 'corporationXYZ'
     */
    entity?: string;
    /**
     *  e.g. 'volunteering', 'presentation', 'talk', 'application', 'conference'
     */
    type?: string;
    [k: string]: unknown;
  }[];
  /**
   * The schema version and any other tooling configuration lives here
   */
  meta?: {
    /**
     * URL (as per RFC 3986) to latest version of this document
     */
    canonical?: string;
    /**
     * A version field which follows semver - e.g. v1.0.0
     */
    version?: string;
    /**
     * Using ISO 8601 with YYYY-MM-DDThh:mm:ss
     */
    lastModified?: string;
    [k: string]: unknown;
  };
}
alexkreidler commented 4 years ago

There's also Quicktype, another in-browser tool for converting from JSON/JSON-Schema to various strongly typed languages (including typescript).

thomasdavis commented 4 years ago

This shouldn't affect the v1 release, not a priority for me so happy if someone else takes charge.

SethFalco commented 3 years ago

When or if we finalize the TypeScript definition, where will we maintain and publish it?

I think it'd be best to create the *.d.ts file manually and maintain it here? While we could use tools to convert the JSON schema, none of them produce desirable results, nor translate the types the way a consumer would expect.

Pros:

Cons:

I think something like this could be good? (May come back to make edits occasionally, especially the docstrings.)

export interface Occupation {

  /**
   * The start date of the occupation.
   */
  startDate?: Date

  /**
   * The end date of the occupation. If undefined or null, may be interpretted
   * as "Present" by implementations.
   */
  endDate?: Date
}

/**
 * Résumé of an individual defined using the JSON Resume schema.
 *
 * @see {@link https://jsonresume.org/}
 */
export interface Resume {

  /** Version of JSON schema is defined against. */
  $schema?: URL

  /** Basic information of an individual. */
  basics?: Basic

  /** Work history. */
  work?: Work[]

  /** Volunteering experience. */
  volunteer?: Volunteer[]

  /** Education history. */
  education?: Education[]

  /** Awards received throughout one's professional career. */
  awards?: Award[]

  /** Certificates received throughout one's professional career. */
  certificates?: Certificate[]

  /** Publications throughout one's career. */
  publications?: Publication[]

  /** Professional skills. */
  skills?: Skill[]

  /** List of languages one speaks. */
  languages?: Language[]

  /** List of interests one has. */
  interests?: Interest[]

  /** List of references one has received */
  references?: Reference[]

  /** Projects one has participated in. */
  projects?: Project[]

  /** The schema version and any other tooling configuration lives here. */
  meta?: Meta
}

/** Basic information of an individual.  */
export interface Basic {

  /**
   * Name of the individual.
   *
   * @see {@link https://www.w3.org/International/questions/qa-personal-names}
   */
  name?: string

  /**
   * The primary position of the individual.
   *
   * For example: Web Developer
   */
  label?: string

  /** URL to an a JPEG or PNG image. */
  image?: URL

  /**
   * Email address to contact the individual.
   *
   * For example: thomas@jsonresume.org
   */
  email?: string

  /**
   * Phone numbers, can be specified in any format.
   *
   * For example: 712-117-2923 or +44 7267038141
   */
  phone?: string

  /**
   * URL to the individuals website.
   *
   * For example: a portfolio or personal homepage
   */
  url?: URL

  /** A short bio about the individual. */
  summary?: string

  /** Where the individual is located. */
  location?: Location

  /** An array of social media networks the individual is on. */
  profiles?: Profile[]
}

/** The address to a physical location. */
export interface Location {

  /**
  * To add multiple address lines, use \n.
  *
  * For example: 1234 Glücklichkeit Straße\nHinterhaus 5. Etage li.
  */
  address?: string

  /** Postal code for the location. */
  postalCode?: string

  city?: string

  /**
   * ISO-3166-1 ALPHA-2 code for the country.
   *
   * For example: US, AU, IN
   */
  countryCode?: string

  /** The general region where you live. Can be a state, county, or province. */
  region?: string
}

/** Social media profile. */
export interface Profile {

  /**
   * The name of the network or platform.
   *
   * For example: Facebook or Twitter
   */
  network?: string

  /**
   * Username on the platform.
   *
   * For example: elonmusk
   */
  username?: string

  /**
   * URL to the profile on the platform.
   *
   * For example: https://twitter.com/elonmusk
   * */
  url?: URL
}

/** A work entry on the résumé. */
export interface Work extends Occupation {

  /**
   * The name of the organization.
   *
   * For example: Facebook
   */
  name?: string

  /** e.g. Menlo Park, CA */
  location?: string

  /** e.g. Social Media Company */
  description?: string

  /** e.g. Software Engineer */
  position?: string

  /** e.g. https://facebook.com */
  url?: URL

  /** An overview of the responsibilities at the organization. */
  summary?: string

  /** Accomplishments achieved during the position. */
  highlights?: string[]
}

export interface Volunteer extends Occupation  {

  /** e.g. Facebook */
  organization?: string

  /** e.g. Software Engineer */
  position?: string

  /** e.g. https://facebook.example.com */
  url?: URL

  /** Give an overview of your responsibilities at the company */
  summary?: string

  /** Specify accomplishments and achievements */
  highlights?: string[]
}

export interface Education extends Occupation  {

  /** e.g. Massachusetts Institute of Technology */
  institution?: string

  /** e.g. https://facebook.example.com */
  url?: URL

  /** e.g. Arts */
  area?: string

  /** e.g. Bachelor */
  studyType?: string

  /** grade point average, e.g. 3.67/4.0 */
  score?: string

  /** List notable courses/subjects */
  courses?: string[]
}

export interface Award {

  /** e.g. One of the 100 greatest minds of the century */
  title?: string

  date?: Date

  /** e.g. Time Magazine */
  awarder?: string

  /** e.g. Received for my work with Quantum Physics */
  summary?: string
}

export interface Certificate {

  /** e.g. Certified Kubernetes Administrator */
  name?: string

  /** e.g. 1989-06-12 */
  date?: string

  /** e.g. https://example.com */
  url?: URL

  /** e.g. CNCF */
  issuer?: string
}

export interface Publication {

  /** e.g. The World Wide Web */
  name?: string

  /** e.g. IEEE, Computer Magazine */
  publisher?: string

  releaseDate?: Date

  /** e.g. https://www.computer.org.example.com/csdl/mags/co/1996/10/rx069-abs.html */
  url?: URL

  /** Short summary of publication. e.g. Discussion of the World Wide Web, HTTP, HTML. */
  summary?: string
}

/** A skill and description of mastery. */
export interface Skill {

  /**
   * The name of the skill.
   *
   * For example: Web Development
   */
  name?: string

  /**
   * A word that describes the level of mastery of the skill.
   *
   * For example: Master
   */
  level?: string

  /** Keywords pertaining to this skill. */
  keywords?: string[]
}

/** Fluency of a language. */
export interface Language {

  /**
   * The display friendly name of a language.
   *
   * For example: English or Spanish
   */
  language?: string

  /**
   * The level of fluency in the language.
   *
   * For example: Fluent or Beginner
   */
  fluency?: string
}

/** Interest or hobby an individual may have. */
export interface Interest {

  /**
   * Name of the interest.
   *
   * For example: Philosophy
   */
  name?: string

  keywords?: string[]
}

/** A reference on the résumé.  */
export interface Reference {

  /** The name of the individual or entity that made the statement. */
  name?: string

  /**
   * For example: Joe blogs was a great employee, who turned up to work at
   * least once a week. He exceeded my expectations when it came to doing
   * nothing. */
  reference?: string
}

/**
 * A project an individual may've particpated in during their professional
 * career.
 */
export interface Project extends Occupation  {

  /**
   * The name of the project.
   *
   * For example: JSON Resume
   */
  name?: string

  /**
   * A short summary of project.
   *
   * For example: Collated works of 2017.
   */
  description?: string

  /** What the individual achieved during the project. */
  highlights?: string[]

  /** Key elements or technologies involved. */
  keywords?: string[]

  /**
   * Where the project or information about the project can be found.
   *
   * For example: https://www.computer.org/csdl/mags/co/1996/10/rx069-abs.html
   */
  url?: URL

  /** The role on this project or in the company. */
  roles?: string[]

  /**
   * Relevant entity/organization affiliations.
   *
   * For example: greenpeace or corporationXYZ
   */
  entity?: string

  /**
   * For example: volunteering, presentation, talk, application, or conference
   */
  type?: string
}

/** Metadata for a résumé. */
export interface Meta {

  /** URL to the latest version of this document. */
  canonical?: URL

  /**
   * The version, should follow semantic versioning.
   *
   * For example: v1.0.0
   *
   * @see {@link https://semver.org/}
   */
  version?: string

  /** The date that the résumé was last modified. */
  lastModified?: Date
}

I'm going to look later at CLI tools to convert a JSON Schema to TypeScript definitions (such as the one referenced in https://github.com/jsonresume/resume-schema/issues/327#issuecomment-605336580) and see if we can improve the results.

It could be, either through a good configuration or restructuring the schema, that this is indeed better. (And I'm really lazy, so I'd love if we didn't have to maintain a separate thing if it can be generated.)

YunYouJun commented 2 years ago

I think we can reverse it. We can write typescript interface to maintain it. And generate json schema by typescript-json-schema.

Before discovering json-resume, i wrote a project called web-resume. I generate resume.schema.json by writing type resume.ts. It works well. And is good for maintenance. We can freely combine the types of ts and generate a schema at the end.