Typescript: 'рдпреВрдирд┐рдпрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрдВрдбреЗрдХреНрд╕ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдореЗрдВ рдХреНрд╡рд┐рдХ рдлрд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдореИрдкреНрдб рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ'

рдХреЛ рдирд┐рд░реНрдорд┐рдд 17 рдордИ 2018  ┬╖  37рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: microsoft/TypeScript

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб:

type K = "foo" | "bar";

interface SomeType {
    [prop: K]: any;
}

рдпрд╣ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджреЗрддрд╛ рд╣реИ:

An index signature parameter type cannot be a union type. Consider using a mapped object type instead.

рдХреЛрдИ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдореИрдк рдХрд┐рдП рдЧрдП рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреНрдпрд╛ рд╣реИрдВ, рддреЛ рдЪрд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рддреНрд╡рд░рд┐рдд рд╕рдорд╛рдзрд╛рди рджреЗрддреЗ рд╣реИрдВ

  • рдЗрдВрдбреЗрдХреНрд╕ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдореИрдк рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИ
  • рдЕрдиреНрдп рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдкрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЪреМрд░рд╛рд╣реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ
  • рдпрджрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ, рддреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ
  • рдпрджрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ extends рдХреНрд▓реЙрдЬрд╝ рд╣реИрдВ, рдпрджрд┐ рдпреБрдХреНрдд рд╡рд╕реНрддреБ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ рдФрд░ рдХрд┐рд╕реА рднреА extends рдХреНрд▓реЙрд╕ рд╣реИрдВ
Error Messages Quick Fixes Moderate Fixed Suggestion help wanted

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рддреБрдо рдпрд╣ рдХреЗрд░ рд╕рдХрддреЗ рд╣реЛ:

type Foo = 'a' | 'b';
type Bar = {[key in Foo]: any};

рд╣рд╛рд▓рд╛рдВрдХрд┐ Bar рдХрд╛ рдХреЛрдИ рдЗрдВрдбреЗрдХреНрд╕ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдирд╣реАрдВ рд╣реИ (рдпрд╛рдиреА, рддрдм рдЖрдк (obj as Bar)[value as Foo] рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ)ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрджреНрдпрдкрд┐ рдпрджрд┐ рдЖрдк рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рдЧреИрд░-рдореБрджреНрджрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рд╕рджрд╛ рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛!

рд╕рднреА 37 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдХреЛрдИ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдореИрдк рдХрд┐рдП рдЧрдП рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреНрдпрд╛ рд╣реИрдВ, рддреЛ рдЪрд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рддреНрд╡рд░рд┐рдд рд╕рдорд╛рдзрд╛рди рджреЗрддреЗ рд╣реИрдВ

+1, рд╕рд┐рд░реНрдл рдпрд╣рд╛рдВ рдЖрдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЙрдореНрдореАрдж рдХрд░ рд░рд╣рд╛ рдерд╛ рдХрд┐ 2.9 рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЗрдВрдбреЗрдХреНрд╕ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдпреВрдирд┐рдпрдиреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВрдЧреЗред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд▓рдВрдмреА рд╡рд╛рдВрдЫрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛ рд░рд╣реА рд╣реИ: # 5683, # 16760, рдЖрджрд┐ред

рддреБрдо рдпрд╣ рдХреЗрд░ рд╕рдХрддреЗ рд╣реЛ:

type Foo = 'a' | 'b';
type Bar = {[key in Foo]: any};

рд╣рд╛рд▓рд╛рдВрдХрд┐ Bar рдХрд╛ рдХреЛрдИ рдЗрдВрдбреЗрдХреНрд╕ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдирд╣реАрдВ рд╣реИ (рдпрд╛рдиреА, рддрдм рдЖрдк (obj as Bar)[value as Foo] рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ)ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрджреНрдпрдкрд┐ рдпрджрд┐ рдЖрдк рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рдЧреИрд░-рдореБрджреНрджрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рд╕рджрд╛ рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛!

рдореИрдВ рдЗрд╕ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛: рд╣рдБрд╕рдирд╛:

рдЕрдиреНрдп рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдкрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЪреМрд░рд╛рд╣реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ

рдпрджрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╡рд░реНрдЧ рд╣реИ рддреЛ рд╣рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?
рдореИрдВ рдХреЗрд╡рд▓ рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ

рдЗрд╕рд▓рд┐рдП рдХреНрд╡рд┐рдХрдлрд╝рд┐рдХреНрд╕ рдХреЗ рдмрд╛рдж рдХреЛрдб рдХрд╛ рдкрд╛рд▓рди рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

type K = "1" | "2"

class SomeType {
    a = 1;
    [prop: K]: any;
}

рдЗрд╕рд▓рд┐рдП рдХреНрд╡рд┐рдХрдлрд╝рд┐рдХреНрд╕ рдХреЗ рдмрд╛рдж рдХреЛрдб рдХрд╛ рдкрд╛рд▓рди рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП ..

@mhegazy рдореИрдВ 3.0.0-rc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЕрднреА рднреА рдореВрд▓ рд░реВрдк рд╕реЗ рдкреЛрд╕реНрдЯ рдХреА рдЧрдИ рд╕рдорд╛рди рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдХреНрдпрд╛ рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ?

рдореИрдВ 3.0.0-рдЖрд░рд╕реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЕрднреА рднреА рдореВрд▓ рд░реВрдк рд╕реЗ рдкреЛрд╕реНрдЯ рдХреА рдЧрдИ рд╕рдорд╛рди рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдХреНрдпрд╛ рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ?

рд╣рд╛рдБред рддреНрд░реБрдЯрд┐ рд╕рд╣реА рд╣реИред рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд╡рд░рд┐рдд рд╕реБрдзрд╛рд░ рдЬреЛрдбрд╝рдХрд░ рдЯреНрд░реИрдХ рдХрд░ рд░рд╣реА рдереА, рдЬреЛ рдХрд┐ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдкреНрд░рдХрд╛рд╢ рд▓реБрдЧрджреА рд╣реИред

2.9.1 рдФрд░ vscode рдХреЗ рд╕рд╛рде рдХреЛрдИ рдХреЛрдб рдХреНрд░рд┐рдпрд╛ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ

@ThaJay рд╣рдо рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдЬрд╛рд╣рд┐рд░ рд╣реИред рдореБрдЭреЗ рдкрд╣рд▓реЗ рд╕рдордпрд░реЗрдЦрд╛ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ, рдмрд╕ рдпрд╣ рдорд╛рди рд▓рд┐рдпрд╛ рдХрд┐ рдпрд╣ рдХрд╛рдлреА рдирдпрд╛ рд╣реЛрдЧрд╛ред Ts рдореЗрдВ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг 3 рдХреЗ рд╕рд╛рде рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ред

рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХреИрд╕реЗ рдХрд░реЗрдВ:

function createRequestTypes(base){
  return ['REQUEST', 'SUCCESS', 'FAILURE'].reduce((acc, type) => {
    acc[type] = `${base}_${type}`
    return acc
  }, {})
}

const user = createRequestTypes('USER')
console.log(user.REQUEST) // error
// just string? like:
interface IRequestType: {[key: string]: string}

рдореИрдВрдиреЗ рдиреАрдЪреЗ рдХреЛрд╢рд┐рд╢ рдХреА, рд╕рдм рд╡рд┐рдлрд▓ рд░рд╣рд╛:

type requestStatus = 'REQUEST' | 'SUCCESS' | 'FAILURE'
type requestTypes = {
  [key in requestStatus]: string
}
// or
interface IRequestTypes {[key: keyType]: string}
// or even
type requestTypes = {
  FAILURE: string,
  SUCCESS: string,
  REQUEST: string
}

@maicWorkGithub рдпрд╣рд╛рдВ рдЖрдк рдЬрд╛рдПрдВ:

const user = createRequestTypes('USER')
console.log(user.REQUEST) 

function createRequestTypes(base:string):requestTypes {
  const result : requestTypes    = {}
  const arr    : requestStatus[] = ['REQUEST', 'SUCCESS', 'FAILURE']  

  return arr.reduce((acc, type) => {
    acc[type] = `${base}_${type}`
    return acc
  }, result)
}


type requestStatus = 'REQUEST' | 'SUCCESS' | 'FAILURE'
type requestTypes = { [key in requestStatus]?: string }

@ рдПрд╣реЙрд░реНрд╕рдХреА рдзрдиреНрдпрд╡рд╛рдж !!

рдмрд╕ рдЙрддреНрд╕реБрдХ рдХреНрдпреЛрдВ type рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди interface рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдХреЛрдИ рд╕рдордЭрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреГрдкрдпрд╛? interface рдРрд╕реА рд╕реАрдорд╛ (рдпрд╛ рд╕реБрд╡рд┐рдзрд╛?) рдХрд╛ рдХрд╛рд░рдг рдХреНрдпрд╛ рд╣реИред

type Foo = 'a' | 'b';
type Bar = {[key in Foo]: any}; // ok
interface Baz {[key in Foo]: any} // =>

// A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.ts(1169)
// A computed property name must be of type 'string', 'number', 'symbol', or 'any'.ts(2464)
// 'Foo' only refers to a type, but is being used as a value here.ts(2693)

рдпрд╣ рдПрдХ рдЕрджреНрднреБрдд рдСрдЯреЛ-рдлрд┐рдХреНрд╕ рдХреА рдЦреЛрдЬ рдереАред рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! :)

рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рднреАред

рддреБрдо рдпрд╣ рдХреЗрд░ рд╕рдХрддреЗ рд╣реЛ:

type Foo = 'a' | 'b';
type Bar = {[key in Foo]: any};

рд╣рд╛рд▓рд╛рдВрдХрд┐ Bar рдХрд╛ рдХреЛрдИ рдЗрдВрдбреЗрдХреНрд╕ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдирд╣реАрдВ рд╣реИ (рдпрд╛рдиреА, рддрдм рдЖрдк (obj as Bar)[value as Foo] рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ)ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрджреНрдпрдкрд┐ рдпрджрд┐ рдЖрдк рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рдЧреИрд░-рдореБрджреНрджрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рд╕рджрд╛ рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛!

Record рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!

type Foo = 'a' | 'b'
type Bar = Record<Foo, any>

рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХрд╛ рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП ...

class Foo {
   a: string;
   b: string;
}

type Bar = {[key in keyof Foo]: any};

рдХреЛрдИ рд╢рдмреНрдж рдирд╣реАрдВ, рдмрд╕ рдореЗрдо:
https://media1.tenor.com/images/23d9d746fc87b3a93298af43dae21f6a/tenor.gif

:)

рдЖрдВрд╢рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдФрд░ рднреА рдмреЗрд╣рддрд░ рд╣реИ

type A = 'x' | 'y' | 'z';
type M = Partial<{
    [key in A]: boolean
}>;

рдХреЛрдИ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдореИрдк рдХрд┐рдП рдЧрдП рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреНрдпрд╛ рд╣реИрдВ, рддреЛ рдЪрд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рддреНрд╡рд░рд┐рдд рд╕рдорд╛рдзрд╛рди рджреЗрддреЗ рд╣реИрдВ

@DanielRosenwasser
рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдХрд╛ рдЙрддреНрддрд░ рдХреНрдпреЛрдВ рдирд╣реАрдВ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореИрдк рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рддреНрд╡рд░рд┐рдд рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдПрдВ - рдпрд╣ рдХреЗрд╡рд▓ рдХреЛрдб рдХреА рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА рдЬреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХреА рдФрд╕рдд рд▓рдВрдмрд╛рдИ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдВрдЧреА: рдЯреНрд░реЛрд▓рдлреЗрд╕:

рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдХрд╣рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЬреЛ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдк рдпрд╛ рдПрдирдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░: { <field>: { <and|or|xor>: <int> } } mongo рдмрд┐рдЯрд╡рд╛рдЗрдЬрд╝ рдСрдкрд░реЗрдЯрд░ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ред

export enum BitwiseOperator {
    and = "and",
    or = "or",
    xor = "xor",
}

export type BitwiseCondition = {
    [key in BitwiseOperator]?: number;
}

рддрдм рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЪрд░ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рд╣реИред

const query: BitwiseCondition = {
  and: 5,
  or: 6  // raise a ts error
};

@ b4dnewz рдЖрдк рдЗрд╕реЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб: https://github.com/Microsoft/TypeScript/issues/10575

@ b4dnewz , рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ 1 рд╕рдВрдкрддреНрддрд┐ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреНрдпреЛрдВ рдирд╣реАрдВ?

export enum BitwiseOperator {
  and = "and",
  or = "or",
  xor = "xor",
}

export type BitwiseCondition = {
  operator: BitwiseOperator;
  value: number;
}

@ рд╡реЙрдирд╡рд┐рдВрдбрд┐рдВрдЧ рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рд▓реМрдЯрд╛ рд╣реБрдЖ рдЖрдХрд╛рд░ рдореЛрдВрдЧреЛрдбрдм рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рд╕реЗ рдЕрд▓рдЧ рд╣реИ

рд╕реБрдЭрд╛рд╡ рдХреЗ рд▓рд┐рдП

рдореИрдВ рдЖрдо-рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рддрд╛рдХрд┐ рдореБрдЭреЗ рд╕рд┐рд░рджрд░реНрдж рд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХреЗ in рд╢рд╛рдпрдж рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдПрдХ рдЙрдЪрд┐рдд рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ

@ b4dnewz рдореЗрд▓рд╛ рдХрд╛рдлреА,

рд╢рд╛рдпрдж рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдПрдХ рд╕рд░рд▓ рд╡рд┐рдХрд▓реНрдк рд╣реИ:

export type BitwiseCondition =
  | { or: number }
  | { xor: number }
  | { and: number }

рдпрд╣ рдирд┐рдХрдЯрддрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рджреЛрд╣рд░рд╛рд╡ рдХреЗ рдмрд┐рдирд╛ рдорд┐рд▓реЗрдЧрд╛

@ b4dnewz рдореЗрд▓рд╛ рдХрд╛рдлреА,

рд╢рд╛рдпрдж рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдПрдХ рд╕рд░рд▓ рд╡рд┐рдХрд▓реНрдк рд╣реИ:

export type BitwiseCondition =
  | { or: number }
  | { xor: number }
  | { and: number }

рдпрд╣ рдирд┐рдХрдЯрддрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рджреЛрд╣рд░рд╛рд╡ рдХреЗ рдмрд┐рдирд╛ рдорд┐рд▓реЗрдЧрд╛

рдпрд╣ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

const query: BitwiseCondition = {
  and: 5,
  or: 6  // raise a ts error
};

рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдкреВрд░реА рдмрд╛рдд рд╣реИ

@ рдЦрд╛рдирд╕рд╛рдорд╛ ,

рдпрд╣ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

export type BitwiseCondition =
  | { or: number }
  | { xor: number }
  | { and: number }

const query: BitwiseCondition = {
  and: 5,
  or: 6  // doesn't raise a ts error!
};

рдУрд╣! рдпрд╣ рдЕрдЬреАрдм рд╣реИ: open_mouth: рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐!

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдирдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдпрд╣рд╛рдВ рдХреА рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рднреА рдкреНрд░рд╕реНрддрд╛рд╡ рдерд╛: https://github.com/microsoft/TypeScript/issues/14094

рдпрд╣ рдЕрднреА рднреА рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рд╕рдВрднрд╡ рд╣реИ ...

рдЗрд╕ stackoverflow рд╕реЗ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░ (рд╕рдмрд╕реЗ рдХрдард┐рди рдкреНрд░рдХрд╛рд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╕реБрдВрджрд░ рд╣реИ ...ред

/*
 XOR boiler plate
*/
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = T | U extends object
  ? (Without<T, U> & U) | (Without<U, T> & T)
  : T | U;
type XOR3<S, T, U> = XOR<S, XOR<T, U>>;

// Code start
export type BitwiseCondition = XOR3<
  { or: number },
  { xor: number },
  { and: number }
>;

const query1: BitwiseCondition = {
  and: 5
};

const query: BitwiseCondition = {
  and: 5,
  or: 6 // raise a ts error
};

рдЕрдЧрд░ рдХреЛрдИ рднреА рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдпрд╛ рдмреЗрд╣рддрд░ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдХрд░реЗрдВ

@mvasin FWIW, рдпрд╣ _appears_ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдпрд╣ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рд╣реИред

type Foo = 'a' | 'b';

type Bar = {
  [key in Foo]: any
}

interface A extends Bar { }

class Wol implements A{
  a: any;
  b: any;
}

рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ 3.5 рдХреЗ рд▓рд┐рдП, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдореБрдЭреЗ рдпрд╣ рдХрд░рдирд╛ рд╣реИ:

export interface DataTableState {
  columnStats: {[key in keyof DataTable]?:{}}
}

рдХреНрдпрд╛ рдпрд╣ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ?

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдПрдирдо рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ ? рдореИрдк рдХрд┐рдпрд╛ рд╣реБрдЖ рдкреНрд░рдХрд╛рд░ рд▓рдЧрднрдЧ рд╡рд╣реА рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ Enum рд╕реЗ рд╣рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рджрд╛рд╡рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдХрд┐ рд╣рд░ рдХреБрдВрдЬреА рдореМрдЬреВрдж рд╣реИ, рдФрд░ рдпрджрд┐ рдХреЛрдИ рдХреБрдВрдЬреА рдореМрдЬреВрдж рд╣реИ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдПрдирдо рдореЗрдВ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

type MyType = {
  [Key: 'foo' | 'bar' | 'zip']: number;
};

рдпрд╣ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

const x: MyType = {
  foo: 1,
  zip: 2
};

рдЬрдмрдХрд┐ рдореИрдВ рд╕рд┐рд░реНрдл рдПрдХ рдореИрдк рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рдХреБрдВрдЬреА рдХреЛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рдерд╛, рдореИрдВ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрдирд╛рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рд╡реЗ рдореМрдЬреВрдж рд╣реИрдВ, рддреЛ рдореВрд▓реНрдп рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдореИрдВ рдореИрдк рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рди рдХреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрдирд╛рддрд╛ рд╣реИ рддреЛ рдХреЛрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдкреНрд░рдХрд╛рд░ рдХрдо рдордЬрдмреВрдд рд╣реЛрддреЗ рд╣реИрдВред

рдЖрдВрд╢рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдФрд░ рднреА рдмреЗрд╣рддрд░ рд╣реИ

type A = 'x' | 'y' | 'z';
type M = Partial<{
    [key in A]: boolean
}>;

рдзрдиреНрдпрд╡рд╛рдж!
рдЙрдкрдпреЛрдЧреА рдЬрдм рдЖрдкрдХреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ

"рдЖрдВрд╢рд┐рдХ" рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдкрд░ рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

type Foo = 'a' | 'b';
let foo1: Record<Foo, number> = { a: 1, b: 2 };
let foo2: Partial<Record<Foo, number>> = { a: 1 };

рдореИрдВ рдЦреБрдж рдХреЛ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ рд╣рд░ рдорд╣реАрдиреЗ рдпрд╛ рддреЛ рдЗрд╕ GitHub рдкреГрд╖реНрда рдкрд░ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдБред

рдореЗрд░рд╛ рдирд╡реАрдирддрдо рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд░рд▓ рд╣реИ:

interface ObjectLiteral {
    [key: string | number]: any
}
export const mapToObjectLiteral = (map: Map<string|number, any>) =>
    Array.from(map).reduce((objLit, [key, value]) => {
        objLit[key] = value
        return objLit
    }, {} as ObjectLiteral)

image

рдореИрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл рдпрд╣ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдореБрджреНрджрд╛ рджрд┐рди-рдкреНрд░рддрд┐рджрд┐рди рдХреЗ рдХрд╛рдореЛрдВ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред

рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

type MapKey = string | number;
type ObjectLiteral<T extends MapKey, V = any> = {
  [P in T extends number ? string : T]: V;
};

export const mapToObjectLiteral = <T extends MapKey, V>(map: Map<T, V>) =>
  Array.from(map).reduce((objLit, [key, value]) => {
    objLit[key as keyof ObjectLiteral<T>] = value;
    return objLit;
  }, {} as ObjectLiteral<T, V>);

// how to make a better type of map ?
const m = new Map<1 | "foo", "a" | "b">();
m.set(1, "a");
m.set("foo", "b");

const o = mapToObjectLiteral(new Map(m));

console.log(o[1], o.foo); // just got an union type of every member of 'o'

https://github.com/microsoft/TypeScript/issues/24220#issuecomment -504285702

рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХрд╛ рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП ...

class Foo {
   a: string;
   b: string;
}

type Bar = {[key in keyof Foo]: any};

рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреАред рдзрдиреНрдпрд╡рд╛рдж! ЁЯЪА

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕