рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА / рдлреНрд░реЗрдорд╡рд░реНрдХ / рдкреИрдЯрд░реНрди рдореЗрдВ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЧрдгрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдмреИрдХрдмреЛрди рдореЙрдбрд▓, рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░рд┐рд╡рд░реНрддрди pluck
, ImmutableJS рд╕рднреА рдРрд╕реЗ рддрдВрддреНрд░ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИрдВред
//backbone
var Contact = Backbone.Model.extend({})
var contact = new Contact();
contact.get('name');
contact.set('age', 21);
// ImmutableJS
var map = Immutable.Map({ name: 'Fran├зois', age: 20 });
map = map.set('age', 21);
map.get('age'); // 21
//pluck
var arr = [{ name: 'Fran├зois' }, { name: 'Fabien' }];
_.pluck(arr, 'name') // ['Fran├зois', 'Fabien'];
рд╣рдо рдЙрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкреА рдФрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рдмрд╛рдзрд╛ рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдз рд╣реИрдВред
рд░реАрдврд╝ рдХреА рд╣рдбреНрдбреА рдХреЗ рдореЙрдбрд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП _proxy_ рдХрд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ:
interface Contact {
name: string;
age: number;
}
pluck
рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ
T[] => U[]
рдЬрд╣рд╛рдБ U, T prop
рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИред
рд╣рд╛рд▓рд╛рдБрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдВрдмрдВрдз рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЧрддрд┐рд╢реАрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред
рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рди T[prop]
рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкреЗрд╢ рдХрд░рдирд╛ рд╣реИ рдЬрд╣рд╛рдВ prop
рд░рд┐рдЯрд░реНрди рдорд╛рди рдпрд╛ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреИрд╕реЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рддрд░реНрдХ рд╣реИред
рдЗрд╕ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рднрд╛рд╖рд╛ рд▓рд┐рдЦ тАЛтАЛрд╕рдХрддреЗ рд╣реИрдВ:
declare module Backbone {
class Model<T> {
get(prop: string): T[prop];
set(prop: string, value: T[prop]): void;
}
}
declare module ImmutableJS {
class Map<T> {
get(prop: string): T[prop];
set(prop: string, value: T[prop]): Map<T>;
}
}
declare function pluck<T>(arr: T[], prop: string): Array<T[prop]> // or T[prop][]
рдЗрд╕ рддрд░рд╣, рдЬрдм рд╣рдо рдЕрдкрдиреЗ рдмреИрдХрдмреЛрди рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рд╣реА рдврдВрдЧ рд╕реЗ get
рдФрд░ set
рдХреЙрд▓ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
interface Contact {
name: string;
age: number;
}
var contact: Backbone.Model<Contact>;
var age = contact.get('age');
contact.set('name', 3) /// error
prop
рд╕реНрдерд┐рд░рдЬрд╛рд╣рд┐рд░ рд╣реИ рдХрд┐ рд╕реНрдерд┐рд░рд╛рдВрдХ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕реЗ рдЗрдВрдбреЗрдХреНрд╕ рдкреНрд░рдХрд╛рд░ ( string
, number
, Symbol
) рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдЗрдП рдПрдХ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ рд╣рдорд╛рд░реЗ Map
рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░:
declare module ImmutableJS {
class Map<T> {
get(prop: string): T[string];
set(prop: string, value: T[string]): Map<T>;
}
}
рдпрджрд┐ T
рдЗрдВрдбреЗрдХреНрд╕реЗрдмрд▓ рд╣реИ, рддреЛ рд╣рдорд╛рд░рд╛ рдирдХреНрд╢рд╛ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
var map = new ImmutableJS.Map<{ [index: string]: number}>;
рдЕрдм get
get(prop: string): number
рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред
рдЕрдм рдХреБрдЫ рдРрд╕реЗ рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдореБрдЭреЗ _correct_ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рджрд░реНрдж рд╣реЛрддрд╛ рд╣реИ, рдЪрд▓реЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рд╣рдорд╛рд░реЗ Map
рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рдеред
рдпрджрд┐ { [index: string]: number }
рдХреЛ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рд╣рдордиреЗ рджрд┐рдпрд╛ рд╣реЛрдЧрд╛
{ [index: number]: number }
рд╕рдВрдХрд▓рдХ рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдмрдврд╝рд╛рдиреА рдЪрд╛рд╣рд┐рдП?
рдЕрдЧрд░ рд╣рдо рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рдмрдЬрд╛рдп pluck
рдЙрдкрдпреЛрдЧ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ:
var contactArray: Contact[] = []
function pluckContactArray(prop: string) {
return _.pluck(myArray, prop);
}
рдпрд╛ рдПрдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд╕рд╛рде рдЬреЛ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрдкрддреНрддрд┐ рдирд╣реАрдВ рд╣реИред
рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП pluck
рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрдард╛рдиреА рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ T[prop]
рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ, T[prop]
{}
рдпрд╛ any
рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдП , рдЕрдЧрд░ рдРрд╕рд╛ рд╣реИ рддреЛ рд╕рдВрдХрд▓рдХ рдХреЛ --noImplicitAny
рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрдард╛рдиреА рдЪрд╛рд╣рд┐рдП?
# 394 рдХрд╛ рд╕рдВрднрд╛рд╡рд┐рдд рдбреБрдкреНрд▓рд┐рдХреЗрдЯ
Https://github.com/Microsoft/TypeScript/issues/1003#issuecomment -61171048 рднреА рджреЗрдЦреЗрдВ
@NoelAbrahams рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдирд╣реАрдВ рд╕реЛрдЪрддрд╛ рдХрд┐ рдпрд╣ # 394 рдХрд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣реИ, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рджреЛрдиреЛрдВ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдмрд╣реБрдд рдкреВрд░рдХ рд╣реИрдВ рдЬреИрд╕реЗ:
class Model<T> {
get(prop: memberof T): T[prop];
set(prop: memberof T, value: T[prop]): void;
}
рдЖрджрд░реНрд╢ рд╣реЛрдЧрд╛
@fdecampredon
contact.set(Math.random() >= 0.5 ? 'age' : 'name', 13)
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?
рдпрд╣ рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдХреЗ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдЧреНрд░рд╛рдл рд╕реЗ рдХрдореЛрдмреЗрд╢ рдПрдХ рд╣реА рдорд╛рдорд▓рд╛ рд╣реИред рдЬреИрд╕реЗ рдореИрдВрдиреЗ рдХрд╣рд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ any
T[prop]
рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рджреВрд╕рд░рд╛ рд╕рдорд╛рдзрд╛рди рдЕрдзрд┐рдХ рддрд╛рд░реНрдХрд┐рдХ рд╣реИ
рд╢рд╛рдирджрд╛рд░ рдкреНрд░рд╕реНрддрд╛рд╡ред рд╕рд╣рдордд, рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╕реБрд╡рд┐рдзрд╛ рд╣реЛрдЧреАред
@fdecampredon , рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣реИред рджрд╛рди рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЦреЗрдВ рдЬрд┐рд╕рдореЗрдВ membertypeof
рд▓рд┐рдП рд╕реБрдЭрд╛рд╡ рд╣реИред
IMO рдпрд╣ рд╕рдм рдПрдХ рд╕рдВрдХреАрд░реНрдг рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИред
@NoelAbrahams рдпрд╣ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИред
memberof T
рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдЬреЛ рдХреЗрд╡рд▓ T
рдЙрджрд╛рд╣рд░рдг рдХреА рд╡реИрдз рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИредT[prop]
T
рдХреА рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдирд╛рдорд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ prop
рддрд░реНрдХ / рдЪрд░ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИредрдПрдХ brifge рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ memberof
рдХреЗ рдкреНрд░рдХрд╛рд░ prop
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ memberof T
ред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВ рдЯрд╛рдЗрдк рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рдореГрджреНрдз рдкреНрд░рдгрд╛рд▓реА рд░рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдСрдкрд░реЗрдЯрд░ рдПрдХ рдЕрдЪреНрдЫреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рде-рд╕рд╛рде memberof
ред
рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИред рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрднреА рддрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ-рд╣реИрд╡реА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╣реБрдд рдорджрдж рдХрд░реЗрдЧрд╛ред
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ-рд╣реИрд╡реА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ
рд╕рдЪред рдлрд┐рд░ рднреА рдпрд╣ рддрдереНрдп рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╕реБрдЭрд╛рд╡ рд╣реИред
рдЕрднреА рддрдХ рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╣реБрдд рдХреБрдЫ рдорджрдж рдХрд░реЗрдЧрд╛ [рдЯрд╛рдЗрдкрд┐рдВрдЧ-рд╣реИрд╡реА рдлреНрд░реЗрдорд╡рд░реНрдХ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП]
рдЙрд╕ рдкрд░ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред рдЙрдкрд░реНрдпреБрдХреНрдд рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдЫрджреНрдо-рд╡рд╕реНрддреБ рдкреИрдЯрд░реНрди рдХреЗ рдмрдЬрд╛рдп рдЯреБрдХрдбрд╝рд╛-рдЯреБрдХрдбрд╝рд╛ рдФрд░ рдХреБрдЫ рд╣рдж рддрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд▓рдЧрддрд╛ рд╣реИред рдореИрдВ # 1003 рдХреА рддрд░реНрдЬ рдкрд░ рдореИрдЬрд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рдХ рд╕рдордЧреНрд░ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ред
any
рдПрдХ рдЧреЗрдЯреНрдЯрд░ рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВред рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рд╢реАрд░реНрд╖ рдкрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдХрд┐ рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░ рдХреЛ рднреА рджреЗрдЦрдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдЬреЛрдбрд╝рдХрд░ - рдорд┐рд╢реНрд░рдг рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣реЛрдЧрд╛:declare module ImmutableJS {
class Map<T> {
get(prop: memberof T): T[prop];
set(prop: memberof T, value: T[prop]): Map<T>;
}
}
@spion , рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдорддрд▓рдм # 394 рд╣реИ? рдпрджрд┐ рдЖрдк рдЖрдЧреЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдереЗ рддреЛ рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЗрдЦреЗрдВрдЧреЗ:
рдореИрдВрдиреЗ рд╡рд╛рдкрд╕реА рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдФрд░ рд╕рдордЧреНрд░ рд╕реБрдЭрд╛рд╡ рдХреЛ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ред
рдпрд╣ рдореЗрд░рд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рдЪрд╛рд░ рдерд╛ рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдпрджрд┐
memberof T
рдХрдИ рддрд░реНрдХ рд╣реИрдВ, рддреЛ рдХреМрди рд╕рд╛membertypeof T
рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ?
get(property: memberof T): membertypeof T;
set(property: memberof T, value: membertypeof T);
рдпрд╣ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ "рдореИрдВ рдХрд┐рд╕ рддрд░реНрдХ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ" рд╕рдорд╕реНрдпрд╛, рд▓реЗрдХрд┐рди
membertypeof
рдирд╛рдо рдЧрд▓рдд рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдХрд┐рд╕реА рдкреНрд░рд╢рдВрд╕рдХ рдХреЛ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЛ рд▓рдХреНрд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
get(property: memberof T): membertypeof property;
set(property: memberof T, value: membertypeof property);
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
get(property: memberof T is A): A;
set(property: memberof T is A, value: A)
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдорд╣рд╛рди рд╕рдорд╛рдзрд╛рди рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдЕрдВрддрд┐рдо рд╕реБрдЭрд╛рд╡ рдореЗрдВ рд╕рднреНрдп рдХреНрд╖рдорддрд╛ рд╣реИред
OK @NoelAbrahams # 394 рдореЗрдВ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдереА рдЬреЛ рдХрдореЛрдмреЗрд╢ рдЙрд╕реА рдЪреАрдЬрд╝ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реА рдереА рдЬреЛ рдпрд╣ рдереАред
рдЕрдм рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ T[prop]
рд╢рд╛рдпрдж рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╕реНрддрд╛рд╡реЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╣реИ, рдФрд░ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рдкреНрд░рд╕реНрддрд╛рд╡ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдореЗрдВ рд╢рд╛рдпрдж рдереЛрдбрд╝рд╛ рдЖрдЧреЗ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрдж рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдкрдХреНрд╖рдкрд╛рддреА рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓рд╛ рд╣реВрдВ;)ред
@fdecampredon , рдЕрдзрд┐рдХ
@ рдиреЛрдПрд▓ рдПрдмреНрд░рд╛рд╣рд╛рдореНрд╕ рдЙрдлрд╝, рдореБрдЭреЗ рд╡рд╣ рд╣рд┐рд╕реНрд╕рд╛ рдпрд╛рдж рдЖ рдЧрдпрд╛ред рдпрдХреАрди рд╣реИ, рд╡реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдорддреБрд▓реНрдп рд╣реИрдВ (рдпрд╣ рдПрдХ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкреЗрд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдпрд╛ рдирд╣реАрдВ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИ)
рдлреНрд▓реЛ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдереЛрдбрд╝рд╛ рдордЬрдмреВрдд рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рдФрд░ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рддрджрд░реНрде рдкреНрд░рдХрд╛рд░ рд╕рдВрдХреАрд░реНрдгрддрд╛ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╣реЛрдЧрд╛ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╣рдо get(prop: string): Contact[prop]
рд╕рд╛рде рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ, рд╕рдВрднрд╡ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╣реИ:
interface Map {
get(prop : string) : Contact[prop];
}
// is morally equivalent to
interface Map {
get(prop : "name") : string;
get(prop : "age") : number;
}
&
рдкреНрд░рдХрд╛рд░ рдСрдкрд░реЗрдЯрд░ (рдЪреМрд░рд╛рд╣реЗ рдкреНрд░рдХрд╛рд░) рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЛ рдорд╛рдирддреЗ рд╣реБрдП, рдпрд╣ рдЗрд╕рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ
interface Map {
get : (prop : "name") => string & (prop : "age") => number;
}
рдЕрдм рдЬрдм рд╣рдордиреЗ рдЕрдкрдиреЗ рдЧреИрд░-рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рдХреЛ рдХреЗрд╡рд▓ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдЪрд╛рд░ (рдХреЛрдИ [prop]
) рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╣рдо рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рд╢реНрди рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХреБрдЫ рд╣рдж рддрдХ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рд╣рдо рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдбрдореА рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ $MapProperties
, $Name
рдФрд░ $Value
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдХреЗрд╡рд▓ рдЯрд╛рдЗрдк рдкрд░реАрдХреНрд╖рдХ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХреЗрд╡рд▓ рдЯрд╛рдЗрдк рдПрдХреНрд╕рдкреНрд░реЗрд╢рди (рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рд╕рд┐рдВрдЯреИрдХреНрд╕) рдХреА рдЕрд╡рдзрд┐ рдореЗрдВ рд╣рдорд╛рд░реЗ рдЙрддреНрдкрдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рдХрд┐ рдХреБрдЫ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
class Map<T> {
get : $MapProperties<T, (prop : $Name) => $Value>
set : $MapProperties<T, (prop : $Name, val : $Value) => void>
}
рдпрд╣ рдЬрдЯрд┐рд▓ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯрд┐рдВрдЧ рдпрд╛ рдЧрд░реАрдм рдЖрджрдореА рдХреЗ рдЖрд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╛рд╕ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдореВрд▓реНрдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдЯрд╛рд▓рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдПрдХ рдЕрдиреНрдп рдХреНрд╖реЗрддреНрд░ рдЬрд╣рд╛рдВ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛, рдЯрд╛рдЗрдк рдХреА рдЧрдИ рд╡рд╕реНрддреБ рдХреЗ рдЧреБрдгреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ:
interface Env {
// pretend this is an actually interesting type
};
var actions = {
action1: function (env: Env, x: number) : void {},
action2: function (env: Env, y: string) : void {}
};
// actions has type { action1: (Env, number) => void; action2: (Env, string) => void; }
var env : Env = {};
var boundActions = {};
for (var action in actions) {
boundActions[action] = actions[action].bind(null, env);
}
// boundActions should have type { action1: (number) => void; action2: (string) => void; }
рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдо рд╕реЗ рдХрдо рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП ( for
рд▓реВрдк рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ), рд▓реЗрдХрд┐рди рдпрд╣ рднреА рд╕рдВрднрд╡рддрдГ рдХрд╛рдлреА рдЦрд┐рдВрдЪрд╛рд╡ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдЕрдЧрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдЙрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдмрд╣реБрдд рдлрд╛рдпрджрд╛ рд╣реЛрдЧрд╛, https://github.com/facebook/react/issues/3398 рджреЗрдЦреЗрдВ
рдЬреИрд╕реЗ https://github.com/Microsoft/TypeScript/issues/1295#issuecomment -64944856, рдЬрдм рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдиреНрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдЖрдкреВрд░реНрддрд┐ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рд╣реЙрд▓реНрдЯрд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд╛рд░рдг рдЬрд▓реНрджреА рд╕реЗ рдЯреВрдЯ рдЬрд╛рддреА рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреНрдпрд╛ рдИрдПрд╕ 6 рдкреНрд░рддреАрдХ рд╕рдорд╕реНрдпрд╛ (# 2012) рд╕реЗ рд╕реАрдЦрдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХрд╛ рдПрдХ рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдЕрднреА рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?
рдордВрдЬреВрд░ рдХреАред
рд╣рдо рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрднрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рд╢рд╛рдЦрд╛ рдореЗрдВ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред
рдмрд╕ рдпрд╣ рд╕реЛрдЪрдХрд░ рдХрд┐ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рдХреМрди рд╕рд╛ рд╕рдВрд╕реНрдХрд░рдг рд▓рд╛рдЧреВ рд╣реЛрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ? Ie рдХреЙрд▓ рд╕реНрдерд▓ рдкрд░ T[prop]
рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдФрд░ рдЙрддреНрд╕реБрдХрддрд╛ рд╕реЗ рдПрдХ рдареЛрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдХреНрдпрд╛ рдпрд╣ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирдпрд╛ рд░реВрдк рдмрдирдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ?
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ # 3779 рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдПрдХ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдФрд░ рдХрдо рдХреНрд░рд┐рдпрд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
interface Map<T> {
get<A>(prop: $Member<T,A>): A;
set<A>(prop: $Member<T,A>, value: A): Map<T>;
}
рдпрд╛ рдпрд╣ A рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ?
рдХреЗрд╡рд▓ рдпрд╣ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВрдиреЗ рдЗрдореНрдпреВрдЯреЗрдмрд▓рдЬреЗрдПрд╕ рдХреЗ рд╕рд╛рде рдЯреАрдПрд╕ рдПрдХреАрдХрд░рдг рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдХреЛрдбреЗрди рдЯреВрд▓ рдмрдирд╛рдпрд╛, рдЬрдмрдХрд┐ рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдзрд╛рди рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ: https://www.npmjs.com/package/tsimmutableред рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬреНрдпрд╛рджрд╛рддрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рд╢рд╛рдпрдж рдпрд╣ рдХрд┐рд╕реА рдХреА рдорджрдж рдХрд░реЗрдЧрд╛ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдХрд┐ рд╕рджрд╕реНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдзрд╛рди ImmutableJS рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
interface Profile {
firstName: string
}
interface User {
profile: Profile
}
let a: Map<User> = fromJS(/* ... */);
a.get('profile') // Type will be Profile, but the real type is Map<Profile>!
@ s-panferov рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
interface ImmutableMap<T> {
get<A extends boolean | number | string>(key : string) : A;
get<A extends {}>(key : string) : ImmutableMap<A>;
get<E, A extends Array<any>>(key : string) : ImmutableList<E>;
}
interface Profile {
}
interface User {
name : string;
profile : Profile;
}
var map : ImmutableMap<User>;
var name = map.get<string>('name'); // string
var profile = map.get<Profile>('profile'); // ImmutableMap<Profile>
рдпрд╣ DOM рдиреЛрдбреНрд╕ рдпрд╛ рджрд┐рдирд╛рдВрдХ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЙрдиреНрд╣реЗрдВ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред https://github.com/facebook/immutable-js/wiki/Converting-from-JS-objects
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░рдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реИ, рдФрд░ рдлрд┐рд░ рдзреАрд░реЗ-рдзреАрд░реЗ рдЗрд╕реЗ рд╡рд╣рд╛рдВ рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╣реИред
рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдореЗрдВ рдПрдХ рдРрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рдЧреИрд░-рдЖрджрд┐рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдореВрд▓реНрдп рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
function getProperty<T extends object>(container: T; propertyName: string) {
return container[propertyName];
}
рдЕрдм рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЯрд╛рд░рдЧреЗрдЯ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рд╣реЛ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЬреЗрдиреЗрд░рд┐рдХ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
function getProperty<T extends object, P>(container: T; propertyName: string) {
return <P> container[propertyName];
}
рддреЛ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рдРрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛:
class C {
member: number;
static member: string;
}
let instance = new C();
let result = getProperty<C, typeof instance.member>(instance, "member");
рдФрд░ result
рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рд╕реЗ number
рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреЙрд▓ рдореЗрдВ 'рд╕рджрд╕реНрдп' рдХрд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╕рдВрджрд░реНрдн рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ: рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдПрдХ _literal_ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ рдЬреЛ рд╣рдореЗрд╢рд╛ рд▓рдХреНрд╖реНрдп рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛ред рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЗрди рджреЛрдиреЛрдВ рдХреЛ рдПрдХрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛ред
рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ рдпрд╣ рджреЗрдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрдХ _generic рдкреИрд░рд╛рдореАрдЯрд░_ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдХрд╛рд░реНрдп рдХрд░реЗрдЧреА, рдФрд░ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдЕрдиреНрдп рдорд╛рдорд▓реЗ рдЪреБрдкрдЪрд╛рдк рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреА рдЕрдирджреЗрдЦреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рд░рдирдЯрд╛рдЗрдо рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдХреЛрдИ рд░реВрдк рдЙрдкрд▓рдмреНрдз рди рд╣реЛ)ред рддреЛ рд╢рдмреНрджрд╛рд░реНрде рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдз рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:
function getProperty<T extends object, PName: string = propertyName>(container: T; propertyName: string) {
return <T[PName]> container[propertyName];
}
рдФрд░ рдЕрдм рдХреЙрд▓ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
let instance = new C();
let result = getProperty<C>(instance, "member");
рдЬреЛ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╣рд▓ рдХрд░реЗрдЧрд╛:
let result = getProperty<C, "member">(instance, "member");
рд╣рд╛рд▓рд╛рдБрдХрд┐, C
рдореЗрдВ member
рдирд╛рдордХ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░ рд╕реНрдерд┐рд░ рд╕рдВрдкрддреНрддрд┐ рд╣реЛрддреА рд╣реИ, рдЙрдЪреНрдЪ-рдкреНрд░рдХрд╛рд░ рдХреА рд╕рд╛рдорд╛рдиреНрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ T[PName]
рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИред рдЪреВрдБрдХрд┐ рдпрд╣рд╛рдБ рдЗрд░рд╛рджрд╛ рдЕрдзрд┐рдХрддрд░ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдЧреБрдгреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╣реИ, typeon
рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд T[PName]
рд░реВрдк рдореЗрдВ рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреБрдЫ рд▓реЛрдЧ рдХрд░рддреЗ рд╣реИрдВред _value reference_, рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░:
function getProperty<T extends object, PName: string = propertyName>(container: T; propertyName: string) {
return <typeon T[PName]> container[propertyName];
}
(рдпрд╣ рддрдм рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдЬрдм T
рдПрдХ рд╕рдВрдЧрдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реЛ, рдЬреИрд╕рд╛ рдХрд┐ typeon
рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ)
рд╕реНрдереИрддрд┐рдХ рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ typeof C
рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
let result = getProperty<typeof C>(C, "member"); // Note it is called with the constructor object
(рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ typeon (typeof C)
typeof C
рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛)
result
рдЕрдм рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рд╕реЗ string
ред
рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрдкрддреНрддрд┐ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
type PropertyIdentifier = string|number|Symbol;
function getProperty<T extends object, PName: PropertyIdentifier = propertyName>(container: T; propertyName: PropertyIdentifier) {
return <typeon T[PName]> container[propertyName];
}
рддреЛ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
рдЕрдм рд╣рдо рдореВрд▓ рд╕рдорд╛рдзрд╛рди рдкрд░ рд╡рд╛рдкрд╕ рдЖрддреЗ рд╣реИрдВ:
function getProperty<T extends object, P>(container: T; propertyName: string) {
return <P> container[propertyName];
}
рдЗрд╕ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдлрд╛рдпрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдкрде рдирд╛рдореЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рди рдХреЗрд╡рд▓ рдкреНрд░рддреНрдпрдХреНрд╖ рдЧреБрдг, рдмрд▓реНрдХрд┐ рдиреЗрд╕реНрдЯреЗрдб рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЧреБрдг:
function getPath<T extends object, P>(container: T; path: string) {
... more complex code here ...
return <P> resultValue;
}
рдФрд░ рдЕрдм:
class C {
a: {
b: {
c: string[];
}
}
}
let instance = new C();
let result = getPath<C, typeof instance.a.b.c>(instance, "a.b.c");
result
рд╕рд╣реА рдврдВрдЧ рд╕реЗ string[]
рдпрд╣рд╛рдБ рдорд┐рд▓реЗрдЧрд╛ред
рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдиреЗрд╕реНрдЯреЗрдб рд░рд╛рд╕реНрддреЛрдВ рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП? рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧреА рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рдСрдЯреЛ-рдкреВрд░реНрддрд┐ рдЙрдкрд▓рдмреНрдз рди рд╣реЛ?
рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЕрд▓рдЧ рд╕рдорд╛рдзрд╛рди рд╕рдВрднрд╡ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рджреВрд╕рд░реА рджрд┐рд╢рд╛ рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдореВрд▓ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдкрд░ рд╡рд╛рдкрд╕:
function getProperty<T extends object, P>(container: T; propertyName: string) {
return <P> container[propertyName];
}
рджреВрд╕рд░реА рджрд┐рд╢рд╛ рд╕реЗ рдЗрд╕реЗ рджреЗрдЦрддреЗ рд╣реБрдП, рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕реНрд╡рдпрдВ рд▓реЗрдирд╛ рдФрд░ рдЗрд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдмрджрд▓рдирд╛ рд╕рдВрднрд╡ рд╣реИ:
function getProperty<T extends object, P>(container: T; propertyName: string = @typeReferencePathOf(P)) {
return <P> container[propertyName];
}
@typeReferencePathOf
рдЕрд╡рдзрд╛рд░рдгрд╛ рдореЗрдВ nameOf
рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рд╛рдкреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрдн typeof instance.member
(рдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ typeon C.member
) рд▓реЗ рдЬрд╛рдПрдЧрд╛, рд╕рдВрдкрддреНрддрд┐ рдкрде member
рдирд┐рдХрд╛рд▓реЗрдВ, рдФрд░ рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ "member"
рд╕рдВрдХрд▓рди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░реЗрдВ рд╕рдордпред рдПрдХ рдХрдо рд╡рд┐рд╢реЗрд╖ рдкреВрд░рдХ @typeReferenceOf
рдкреВрд░реА рд╕реНрдЯреНрд░рд┐рдВрдЧ "typeof instance.member"
рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдЧрд╛ред
рддреЛ рдЕрдм:
getProperty<C, typeof instance.subObject>(instance);
рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдВрдЧреЗ:
getProperty<C, typeof instance.subObject>(instance, "subObject");
рдФрд░ getPath
рд▓рд┐рдП рд╕рдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
getPath<C, typeof instance.a.b.c>(instance);
рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдВрдЧреЗ:
getPath<C, typeof instance.a.b.c>(instance, "a.b.c");
рдЪреВрдБрдХрд┐ @typeReferencePathOf(P)
рдХреЗрд╡рд▓ рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рддрд░реНрдХ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
getPath<C, SomeTypeWhichIsNotAPath>(instance, "member.someSubMember.AnotherSubmember.data");
рдпрджрд┐ рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ @typeReferencePathOf()
рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ undefined
рдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ ""
рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЖрдВрддрд░рд┐рдХ рдорд╛рд░реНрдЧ рдирд╣реАрдВ рдерд╛, рддреЛ рдпрд╣ ""
рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдЧрд╛ред
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд▓рд╛рдн:
typeof
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╕рдордп рд╕реНрд╡рддрдГ рдкреВрд░реНрдгрддрд╛ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╕рдВрдХрд▓рди-рд╕рдордп рдкрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕реЗ рдЗрд╕реЗ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрдЬрд╛рдп рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рдЬрд╛рдБрдЪ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИредtypeon
рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдорд░реНрдерди рдХрд░ рд╕рдХрддрд╛ рд╣реИ)ред+1
рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛! рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝рд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдЪрд░реНрдЪрд╛ рдХреЛ рдкрд╛рдпрд╛, рддреЛ рдЖрдЗрдП рдпрд╣рд╛рдВ рдЪрд░реНрдЪрд╛ рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣рд╛рдБ рдореЗрд░реЗ рдЧреИрд░ рдкреНрд░рд╕реНрддреБрдд рдореБрджреНрджреЗ рд╕реЗ рдПрдХ рдЙрджреНрдзрд░рдг рд╣реИ:
рдкреНрд░рд╢реНрди : .d.ts рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреИрд╕реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд╣рд╛рдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ?
function mapValues(obj, fn) {
return Object.keys(obj)
.map(key => ({key, value: fn(obj[key], key)}))
.reduce((res, {key, value}) => (res[key] = value, res), {})
}
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди (рдереЛрдбрд╝реЗ рдмрджрд▓рд╛рд╡ рдХреЗ рд╕рд╛рде) рд▓рдЧрднрдЧ рд╣рд░ рд╕рд╛рдорд╛рдиреНрдп "рдмрд░реНрддрдиреЛрдВ" рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЬрдВрдЧрд▓реА рдореЗрдВ mapValues
рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рд╣реИрдВ:
рдПред _Object-as-a -_ -_ _ _ рдЬрд╣рд╛рдВ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдЧрддрд┐рд╢реАрд▓ рд╣реИрдВ, рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рд╣реИ, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ рдореЛрдиреЛрдореЛрд░реНрдлрд┐рдХ (рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛)
var obj = {'a': 1, 'b': 2, 'c': 3};
var res = mapValues(x, val => val * 5); // {a: 5, b: 10, c: 15}
console.log(res['a']) // 5
рдмреА _Object-as-a-_ -Record _ рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЕрдкрдирд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬрдмрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯреНрд░рд┐рдХ рдкреЙрд▓реАрдореЙрд░реНрдлрд┐рдХ рд╣реИ (рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреНрд╡рд╛рд░рд╛)
var obj = {a: 123, b: "Hello", c: true};
var res = mapValues(p, val => [val]); // {a: [123], b: ["Hello"], c: [true]}
console.log(res.a[0].toFixed(2)) // "123.00"
рд╡рд░реНрддрдорд╛рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде mapValues
рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЙрдкрд▓рдмреНрдз рдЗрдВрд╕реНрдЯреНрд░реВрдореЗрдВрдЯреЗрд╢рди рд╣реИ:
declare function mapValues<T1, T2>(
obj: {[key: string]: T1},
fn: (arg: T1, key: string) => T2
): {[key: string]: T2};
рдпрд╣ рджреЗрдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ _Object-as-a -_ -_ _ _ _ рдЗрдВрд╕реНрдкреЗрдХреНрд╢рди рдХрд╛ рдХреБрдЫ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ 1 рдкрд░рд┐рдгрд╛рдо рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ _Object-as-a-_ _Record _ рдЗрд░рд╛рджрд╛ рдерд╛ред
рдкреНрд░рдХрд╛рд░ {p1: T1, p2: T2, ...pn: Tn}
{[key: string]: T1 | T2 | ... | Tn }
рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реБрдП рдФрд░ рд░рд┐рдХреЙрд░реНрдб рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдЦрд╛рд░рд┐рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
console.log(res.a[0].toFixed(2))
рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛;console.log((<number>res['a'][0]).toFixed(2))
рдореЗрдВ рджреЛ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдФрд░ рддреНрд░реБрдЯрд┐-рдкреНрд░рд╡рдг рд╕реНрдерд╛рди рд╣реИрдВ: рдЯрд╛рдЗрдк-рдХрд╛рд╕реНрдЯ рдФрд░ рдордирдорд╛рдирд╛ рд╕рдВрдкрддреНрддрд┐ рдирд╛рдоред1, 2 - рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рдЬреЛ ES рд╕реЗ TS рдХреЗ рд▓рд┐рдП рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд░рддрд╛ рд╣реИ
type Numbers<p extends string> = { ...p: number };
type NumbersOpt<p extends string> = {...p?: number };
type ABC = "a" | "b" | "c";
type abc = Numbers<ABC> // abc = {a: number, b: number, c: number}
type abcOpt = NumbersOpt<ABC> // abcOpt = {a?: number, b?:number, c?: number}
function toFixedAll<p extends string>(obj: {...p: number}, precision):{...p: string} {
var result: {...p: string} = {} as any;
Object.keys(obj).forEach((p:p) => {
result[p] = obj[p].toFixed(precision);
});
return result;
}
var test = toFixedAll({x:5, y:7}, 3); // { x: "5.00", y: "6.00" }, p inferred as "x"|"y"
console.log(test.y.length) // 4 test.y: string
рдЙрджрд╛рд╣рд░рдг:
declare function mapValues<p extends string, T1[p], T2[p]>(
obj:{...p: T1[p]}, fn:(arg: T1[p]) => T2[p]
): {...p: T2[p]};
рдЙрджрд╛рд╣рд░рдг:
class C<Array<T>> {
x: T;
}
var v1: C<string[]>; // v1.x: string
рд╕рднреА рддреАрди рдЪрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╣рдо рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ
declare module Backbone {
class Model<{...p: T[p]}> {
get(prop: p): T[p];
set(prop: p, value: T[p]): void;
}
}
declare module ImmutableJS {
class Map<{...p: T[p]}> {
get(prop: p): T[p];
set(prop: p, value: T[p]): this;
}
}
declare function pluck<p extends string, T[p]>(
arr: Array<{...p:T[p]}>, prop: p
): Array<T[p]>
рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рд╕рд┐рдВрдЯреИрдХреНрд╕ @fdecampredon рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдХреНрд░рд┐рдпрд╛ рд╣реИ
рд▓реЗрдХрд┐рди рдореИрдВ рдХрд▓реНрдкрдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХрд┐ рдореВрд▓ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде mapValues
рдпрд╛ combineReducers
рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдХреИрд╕реЗ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред
function combineReducers(reducers) {
return (state, action) => mapValues(reducers, (reducer, key) => reducer(state[key], action))
}
рдореЗрд░реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдЗрд╕рдХреА рдШреЛрд╖рдгрд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:
declare function combineReducers<p extends string, S[p]>(
reducers: { ...p: (state: S[p], action: Action) => S[p] }
): (state: { ...p: S[p] }, action: Action) => { ...p: S[p] };
рдХреНрдпрд╛ рдпрд╣ рдореВрд▓ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рд╕реНрдкрд╖реНрдЯ рд╣реИ?
@spion , @fdecampredon ?
@Artazor рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд╕реБрдзрд╛рд░ рд╣реИред рдЕрдм рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рдореЗрд░реЗ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ:
user.id
рдФрд░ user.name
рдорд╛рдирдХрд░ user.id
number
рдФрд░ string
рдЕрдиреБрд╕рд╛рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрддрдВрдн рдкреНрд░рдХрд╛рд░ рд╣реИрдВ рдпрд╛рдиреА Column<number>
рдФрд░ Column<string>
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦреЗрдВ select
рдЬреЛ рд▓реЗрддрд╛ рд╣реИ:
select({id: user.id, name: user.name})
рдФрд░ Query<{id: number; name: string}>
select<T>({...p: Column<T[p]>}):Query<T>
рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдЬрд╛рдБрдЪ рдХреА рдФрд░ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рд▓рдЧрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдк T рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд┐рдирд╛рд╢рдХрд╛рд░реА рд░реВрдк рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА? рдЕрд░реНрдерд╛рдд
select<T>({...p: Column<T[p]>}):Query<{...p:T[p]}>
@Artazor рдкреВрдЫрдирд╛ рднреВрд▓ рдЧрдпрд╛, рдХреНрдпрд╛ p extends string
рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ?
рдХреНрдпрд╛ рдРрд╕рд╛ рдХреБрдЫ рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛?
select<T[p]>({...p: Column<T[p]>}):Query<{...p:T[p]}>
рдпрд╛рдиреА рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП T [p] {...p:Column<T[p]>}
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдПрдХ рдФрд░ рд╕рд╡рд╛рд▓, рдпрд╣ рдХреИрд╕реЗ рд╕рд╣реА рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИ?
@spion рдореБрдЭреЗ рдЖрдкрдХреА рдмрд╛рдд рд╕рдордЭ рдореЗрдВ рдЖ рдЧрдИ рд╣реИ - рдЖрдкрдиреЗ T[p]
рдореБрдЭреЗ рдЧрд▓рдд рд╕рдордЭрд╛ рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рдореЗрд░реА рдЧрд▓рддреА рд╣реИ), рдореЗрд░рд╛ рдорддрд▓рдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдЪреАрдЬ рд╕реЗ рд╣реИ, рдФрд░ рдЖрдк рдЙрд╕ p extends string
рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред
рдЪрд▓реЛ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЪрд╛рд░ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ: List
, Tuple
, Dictionary
рдФрд░ Record
ред рд╣рдо рдЙрдиреНрд╣реЗрдВ _conceptual data structure_ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдЙрдирдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ:
рд╡реИрдЪрд╛рд░рд┐рдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ | рджреНрд╡рд╛рд░рд╛ рдкрд╣реБрдБрдЪ | ||
---|---|---|---|
рдПред рдкрдж (рд╕рдВрдЦреНрдпрд╛) | рдмреА рдЪрд╛рднреА (рд╕реНрдЯреНрд░рд┐рдВрдЧ) | ||
рдХреА рдЧрд┐рдирддреА рдЖрдЗрдЯрдо | 1. рдЪрд░ (рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рднреВрдорд┐рдХрд╛) | рд╕реВрдЪреА | рд╢рдмреНрджрдХреЛрд╢ |
2. рдирд┐рдпрдд (рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдЕрдкрдиреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддрд╛ рд╣реИ) | рдЯрдкрд▓ | рдЕрднрд┐рд▓реЗрдЦ |
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдЗрди рдЪрд╛рд░ рдорд╛рдорд▓реЛрдВ рдХреЛ рджреЛ рднрдВрдбрд╛рд░рдг рд░реВрдкреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: a Array
- a1 рдФрд░ a2 рдХреЗ рд▓рд┐рдП , рдФрд░ Object
- b1 рдФрд░ b2 рдХреЗ рд▓рд┐рдП ред
_Note 1 _ред рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдХрд╣рдирд╛ рд╕рд╣реА рдирд╣реАрдВ рд╣реИ рдХрд┐
Tuple
Array
рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЗрд╡рд▓ "рд╕рддреНрдп" рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░arguments
рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛArray
ред рдлрд┐рд░ рднреА, рд╡реЗ рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рд╡рд┐рдирд┐рдореЗрдп рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рд╡рд┐рдирд╛рд╢рдХрд╛рд░реА рдФрд░Function.prototype.apply
рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЬреЛ рдореЗрдЯрд╛-рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рджрд░рд╡рд╛рдЬрд╛ рдЦреЛрд▓рддрд╛ рд╣реИред рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рднреА Tuples рдореЙрдбрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП Arrays рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддреА рд╣реИред_Note 2 _ред рдЬрдмрдХрд┐ рдИрдПрд╕ 6
Map
рд░реВрдк рдореЗрдВ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╢рдмреНрджрдХреЛрд╢ рдХреА рдкреВрд░реНрдг рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдмрд╛рдж рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдмреНрд░реЗрдВрдбрди рдИрдЪ рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХRecord
рдФрд░ рдПрдХ рд╕реАрдорд┐рддDictionary
(рд╕рд╛рде рджреЗрдиреЗ рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдирд┐рд░реНрдгрдп) рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреБрдВрдЬреА рдХреЗрд╡рд▓)Object
(рдЬрд╣рд╛рдВobj.prop
obj["prop"]
рдмрд░рд╛рдмрд░ рд╣реИ) рдХреЗ рдПрдХ рд╣реА рд╣реБрдб рдХреЗ рддрд╣рдд рдкреВрд░реА рднрд╛рд╖рд╛ рдХрд╛ рд╕рдмрд╕реЗ рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рддрддреНрд╡ рдмрди рдЧрдпрд╛ (рдореЗрд░реА рд░рд╛рдп рдореЗрдВ)ред
рдпрд╣ рд╢рд╛рдк рдФрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╢рдмреНрджрд╛рд░реНрде рджреЛрдиреЛрдВ рдХрд╛ рдЖрд╢реАрд░реНрд╡рд╛рдж рд╣реИред рдпрд╣ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЛ рддреБрдЪреНрдЫ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░реЛрдВ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ _programming_ рдФрд░ _meta-programming_ рдХреЗ рд╕реНрддрд░ рдХреЗ рдмреАрдЪ рд▓рдЧрднрдЧ рд╢реВрдиреНрдп рдорд╛рдирд╕рд┐рдХ рд▓рд╛рдЧрдд (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдмрд┐рдирд╛ рд╕реВрдЪрдирд╛ рдХреЗ!) рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдлрд▓рддрд╛ рдХрд╛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред
рдЕрдм рдпрд╣ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдЕрдЬреАрдм рд╢рдмреНрджрд╛рд░реНрде рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЬрдм рд╣рдо рд╕реЛрдЪрддреЗ рд╣реИрдВ рдХрд┐ _programming_ рд╕реНрддрд░ рдкрд░ рд╕рдм рдареАрдХ рд╣реИ:
рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реНрддрд░ рдкрд░ рдкреНрд░рдХрд╛рд░ | рджреНрд╡рд╛рд░рд╛ рдкрд╣реБрдБрдЪ | ||
---|---|---|---|
рдПред рдкрдж (рд╕рдВрдЦреНрдпрд╛) | рдмреА рдЪрд╛рднреА (рд╕реНрдЯреНрд░рд┐рдВрдЧ) | ||
рдХреА рдЧрд┐рдирддреА рдЖрдЗрдЯрдо | 1. рдЪрд░ (рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рднреВрдорд┐рдХрд╛) | рдЯреА [] | {[рдХреБрдВрдЬреА: рд╕реНрдЯреНрд░рд┐рдВрдЧ]: рдЯреА} |
2. рдирд┐рдпрдд (рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдЕрдкрдиреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддрд╛ рд╣реИ) | [T1, T2, ...] | {рдХреА рез: рдЯреА рез, рдХреА реи: рдЯреА реи, ...} |
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЬрдм рд╣рдо _meta-programming_ рд╕реНрддрд░ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ _programming_ рд╕реНрддрд░ рдкрд░ рддрдп рдХреА рдЧрдИ рдЪреАрдЬреЗрдВ рдЕрдЪрд╛рдирдХ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ! рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рдЕрдЪрд╛рдирдХ рдЯреНрдпреВрдкрд▓реНрд╕ рдФрд░ рдлрдВрдХреНрд╢рди рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдзреЛрдВ рдХреЛ рдкрд╣рдЪрд╛рдирддреЗ рд╣реИрдВ рдФрд░ # 5453 (рд╡реИрд░рд┐рдПрдбрд┐рдХ рдХрд┐рдВрдбреНрд╕) рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрдЯреНрд░реЛрдкреЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЬрд░реВрд░рддреЛрдВ рдХреЗ рдХреЗрд╡рд▓ рдЫреЛрдЯреЗ (рд▓реЗрдХрд┐рди рдХрд╛рдлреА рдорд╣рддреНрд╡рдкреВрд░реНрдг) рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдХрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ - рдПрдХ рдФрдкрдЪрд╛рд░рд┐рдХ рдХреЛ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рджреЗрдХрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХрд╛ рд╕рдВрдпреЛрдЬрдиред рдмрд╛рдХреА рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░:
function f<T>(a: number, ...args:T) { ... }
f<[string,boolean]>(1, "A", true);
рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрджрд┐ # 6018 рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рддреЛ рдлрдВрдХреНрд╢рди рдХреНрд▓рд╛рд╕ рдЬреИрд╕рд╛ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ
declare class Function<This, TArgs, TRes> {
This::(...args: TArgs): TRes;
call(self: This, ...args: TArgs): TRes;
apply(self: This, args: TArgs): TRes;
// bind needs also formal pattern matching:
bind<[...TPartial, ...TCurried] = TArgs>(
self: This, ...args: TPartial): Function<{}, TCurried, TRes>
}
рдпрд╣ рдорд╣рд╛рди рд╣реИ рд▓реЗрдХрд┐рди рд╡реИрд╕реЗ рднреА рдЕрдзреВрд░рд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдЕрд╕рд╛рдЗрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
function extractAndWrapAll(...args) {
return args.map(x => [x]);
}
// wrapAll(1,"A",true) === [[1],["A"],[true]]
рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╣рдо рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдХреБрдЫ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдХреА рдЬрд░реВрд░рдд рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдВрдХрд▓рди-рд╕рдордп рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд░рдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдЬреЛ рдХрд┐ рдкреНрд░рдХрд╛рд░ (рдлреЗрд╕рдмреБрдХ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдореЗрдВ) рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдпрд╣ рддрдм рд╣реА рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдЬрдм (рдФрд░ рдЕрдЧрд░) рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЕрдЧрд▓реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд╕рд╛рдордиреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрджреНрдпрддрди рдХреЛ рддреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬреЛрдЦрд┐рдо рдХреЗ рдмрд┐рдирд╛ рдЗрд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╕реНрдерд┐рд░ рд╣реЛрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдореЗрдВ рдкреВрд░реНрдг рдореЗрдЯрд╛-рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕рдорд░реНрдерди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреБрдЫ рдХрдо рдХрдЯреНрдЯрд░рдкрдВрдереА рдЪрд╛рд╣рд┐рдП рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдкреНрд░рджрд░реНрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ _object рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░_ рдХреА рдзрд╛рд░рдгрд╛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБред рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдпрд╣ рдпрд╛ рддреЛ рд╣реИ
рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдкреВрд░реНрдгрд╛рдВрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рдЯреНрдпреВрдкрд▓ рдЬреИрд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред
type ZeroToFive = 0 | 1 | 2 | 3 | 4 | 5;
// or
type ZeroToFive = 0 .. 5; // ZeroToFive extends number (!)
рдкреВрд░реНрдгрд╛рдВрдХ рд╢рд╛рдмреНрджрд┐рдХреЛрдВ рдХреЗ рдирд┐рдпрдо рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ;
рддрдм рд╣рдо рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдПрдмреНрд╕реНрдЯреНрд░рдХреНрд╢рди рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рд░реЗрд╕реНрдЯ / рд╕реНрдкреНрд░реЗрдб рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ:
{...Props: T }
рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде: рдпрд╣рд╛рдВ Props
рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ рдЬреЛ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдХреНрд╡рд╛рдВрдЯрд┐рдлрд╛рдпрд░ рдХреЗ рддрд╣рдд рдмрд╛рдзреНрдп рд╣реИ:
<Props extends string> {...Props: T } // every property has type T
<Index extends number> {...Index: T } // every item has type T
// the same as T[]
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕реЗ рдЯрд╛рдЗрдк рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╕реНрдХреЛрдк рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рд╕реНрдХреЛрдк рдХреЗ рдирд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╣реАрдВ рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рджреЛрд╣рд░рд╛ рд╣реИ: рдЬрдм рдЖрд░рд╛рдо / рдкреНрд░рд╕рд╛рд░ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдпрд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдкрд░ рдЕрдореВрд░реНрддрддрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдЬрдм рдЗрд╕реЗ рдПрдХ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдпрд╣ рд╕реНрдЯреНрд░рд┐рдВрдЧ (рдпрд╛ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░) рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред
declare class Object {
static keys<p extends string, q extends p>(object{...q: {}}): p[];
}
рдФрд░ рдпрд╣рд╛рдБ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рднрд╛рдЧ рд╣реИ: _Key рдЖрд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░_
рд╣рдо рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВ: T for Prop
(рдореИрдВ рдЗрд╕ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ T [Prop] рдХреЗ рдмрдЬрд╛рдп рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдЖрдкрдХреЛ рднреНрд░рдорд┐рдд рдХрд░рддрд╛ рд╣реИ) рдЬрд╣рд╛рдВ Prop рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдЪрд░ рдХрд╛ рдирд╛рдо рд╣реИ рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдЕрдореВрд░реНрдд рд░рдЦрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП <Prop extends string, T for Prop>
рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рдкреНрд░рдХрд╛рд░ рд╢рд╛рдмреНрджрд┐рдХ рджрд╛рдпрд░реЗ рдореЗрдВ рджреЛ рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХрд╛рд░, Prop
рдФрд░ T
рдЬрд╣рд╛рдВ рдпрд╣ рдЬреНрдЮрд╛рдд рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢реЗрд╖ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП p
рдХреЗ Prop
рд╡рд╣рд╛рдБ рдпрд╣ T
рдЦреБрдж рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛ред
рд╣рдо рдпрд╣ рдирд╣реАрдВ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рд╣реИ рдЬрд┐рд╕рдХреА рд╕рдВрдкрддреНрддрд┐
Props
рдФрд░ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░T
! рд╣рдо рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВред рдЯрд╛рдЗрдк рдЯреА рдХреЛ Props рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣рд╕рдВрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдм!
рдпрд╣ рд╣рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рджреЗрддрд╛ рд╣реИ
function unwrap<P extends string, T for P>(obj:{...P: Maybe<T>}): Maybe<{...P: T}> {
...
}
unwrap({a:{value:1}, b:{value:"A"}, c:{value: true}}) === { a: 1, b: "A", c: true }
// here actual parameters will be inferred as
unwrap<"a"|"b"|"c", {a: number, b: string, c: boolean}>
рд╣рд╛рд▓рд╛рдБрдХрд┐ рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рд╡рд╕реНрддреБ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рдЕрдореВрд░реНрдд рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рдореЗрдВ T for P
рдХрд╛ рдЙрдкрдпреЛрдЧ tuples рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЕрдореВрд░реНрдд рджреГрд╢реНрдпреЛрдВ рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм P рд╕рдВрдЦреНрдпрд╛ ( @JsonFreeman ?) рдХрд╛ рдЙрдк-рдкреНрд░рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ?
рдЬрдм T
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд╣реАрдВ рди рдХрд╣реАрдВ {...P: .... T .... }
рдЕрдВрджрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдпрд╣ рдЙрд╕ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдмрд┐рд▓реНрдХреБрд▓ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдореЗрд░рд╛ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рд╣реИред
рдХрд┐рд╕реА рднреА рдкреНрд░рд╢реНрди, рд╡рд┐рдЪрд╛рд░, рдЖрд▓реЛрдЪрдирд╛ рдХрд╛ рдмреЗрд╕рдмреНрд░реА рд╕реЗ рдЗрдВрддрдЬрд╛рд░ -)
рдареАрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП extends string
рдХреЛ рдПрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рд░рдгрд┐рдпреЛрдВ (рдФрд░ рд╡реИрд░рд╛рдбрд┐рдХ рддрд░реНрдХ) рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдерд┐рд░рд╛рдВрдХ (рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ) рд╣реИред рдорд┐рдард╛рдИ!
рд╣рдо рдпрд╣ рдирд╣реАрдВ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ T рд╣реИрдВ! рд╣рдо рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВред рдЯрд╛рдЗрдк рдЯреА рдХреЛ Props рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣рд╕рдВрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдм!
рдореЗрд░рд╛ рдпрд╣ рдорддрд▓рдм рдирд╣реАрдВ рдерд╛, рдореЗрд░рд╛ рдорддрд▓рдм рдпрд╣ рдерд╛ рдХрд┐ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ рдЯреА [рдкреА] рд╣реИрдВ, рдкреА рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ред рдЕрдЧрд░ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрдВрддрд░реНрдЬреНрдЮрд╛рди рд╣реИ, рддреЛ рдореИрдВ рдпрд╣реА рд░рдЦреВрдВрдЧрд╛ред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдереЛрдбрд╝рд╛ рдФрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ рд▓рдЧрддрд╛ рд╣реИред
рдХреНрдпрд╛ рд╡реИрд░рд┐рдПрдмрд▓ рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП unwrap
рд▓рд┐рдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИ?
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ, рдореБрдЭреЗ рд╕рд┐рд░реНрдл рдпрд╣ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рд╡реИрд░рд╛рдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдкрдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИред
рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░,
рдореИрдВ рд╣реИрд░рд╛рди рд╣реВрдБ рдХрд┐ рдореИрдВ рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд░реВрдВ рдФрд░ рдЗрд╕ рдЪрд░реНрдЪрд╛ рдХреЛ рдкрд╛рдпрд╛ред
рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ:
рдореЗрд░реЗ рдкрд╛рд╕ RpcManager.call(command:Command):Promise<T>
рд╡рд┐рдзрд┐ рд╣реИ, рдФрд░ рдЙрдкрдпреЛрдЧ рдРрд╕рд╛ рд╣реЛрдЧрд╛:
RpcManager.call(new GetBalance(123)).then((result) => {
// here I want that result would have a type.
});
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╛рдзрд╛рди рдХреА рддрд░рд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:
interface Command<T> {
responseType:T;
}
class GetBalance implements Command<number> {
responseType: number; // somehow this should be avoided. maybe Command should be abstract class.
constructor(userId:number) {}
}
class RpcManager {
static call(command:Command):Promise<typeof command.responseType> {
}
}
or:
class RpcManager {
static call<T>(command:Command<T>):Promise<T> {
}
}
рдЗрд╕ рдкрд░ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?
@ antanas-arvasevicius рдЙрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЕрдВрддрд┐рдо рдХреЛрдб рдмреНрд▓реЙрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдПред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рдкреНрд░рд╢реНрди рд╣реИ; рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдпрд╛ рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рдмрдЧ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИ рддреЛ рдПрдХ рд╕рдорд╕реНрдпрд╛ рджрд░реНрдЬ рдХрд░реЗрдВред
рд╣рд╛рдп, рд░рдпрд╛рди, рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рдореИрдВрдиреЗ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдХрд┐ рдХреЛрдб рдХреЗ рдЕрдВрддрд┐рдо рдмреНрд▓реЙрдХ рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рддреНрд╡рд░рд┐рдд рдбреЗрдореЛ:
interface Command<T> { }
class MyCommand implements Command<{status:string}> { }
class RPC { static call<T>(command:Command<T>):T { return; } }
let response = RPC.call(new MyCommand());
console.log(response.status);
//output: error TS2339: Property 'status' does not exist on type '{}'.
//tested with: Version 1.9.0-dev.20160222
рдЦреЗрдж рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдЗрд╕ рдореБрджреНрджреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ :)
рдХреНрдпрд╛ рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП?
рдПрдХ рдЧреИрд░-рд╕рд╛рдорд╛рдиреНрдп рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ; рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдЖрдкрдХреЛ _never_ рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рдШреЛрд╖рдгрд╛рдУрдВ рдореЗрдВ рдЕрдкреНрд░рдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЕрд░реНрдерд╣реАрди рд╣реИрдВред рдпрджрд┐ рдЖрдк T
рдЙрдкрднреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдмрд╕ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
interface Command<T> { foo: T }
class MyCommand implements Command<{status:string}> { foo: { status: string; } }
class RPC { static call<T>(command:Command<T>):T { return; } }
let response = RPC.call(new MyCommand());
console.log(response.status);
рдпрд╣ рд╕рд┐рд░реНрдл рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╣реИ! рдзрдиреНрдпрд╡рд╛рдж!
рдореИрдВрдиреЗ рдирд╣реАрдВ рд╕реЛрдЪрд╛ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдВрджрд░ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░
рдЯреАрдПрд╕ рдЙрд╕реЗ рдирд┐рдХрд╛рд▓реЗрдЧрд╛ред
рдлрд░рд╡рд░реА 22, 2016 11:56 рдЕрдкрд░рд╛рд╣реНрди, "рд░рдпрд╛рди рдХреИрд╡рд╛рдиреБрдШ" рд╕реВрдЪрдирд╛рдПрдБ @ithub.com рдиреЗ рд▓рд┐рдЦрд╛:
рдПрдХ рдЧреИрд░-рд╕рд╛рдорд╛рдиреНрдп рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ; рдореЗрдВ
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдЖрдкрдХреЛ _never_ рдХреЗ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдЕрдкреНрд░рдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП
рдШреЛрд╖рдгрд╛рдПрдВ рдирд┐рд░рд░реНрдердХ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЯреА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмрд╕ рд╕рдм рдХреБрдЫ
рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрдорд╛рдВрдб
{foo: T} рд╡рд░реНрдЧ MyCommand рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдХрдорд╛рдВрдб <{status: string}> {foo: {status: string; }} рд╡рд░реНрдЧ RPC {рд╕реНрдерд┐рд░ рдХреЙрд▓ (рдХрдорд╛рдВрдб: рдХрдорд╛рдВрдб ): рдЯреА {рд╡рд╛рдкрд╕реА; }}
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдВ = RPC.call (рдирдпрд╛ MyCommand ());
рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ (рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛.рд╕реНрдЯреИрдЯрд╕);-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рдЙрддреНрддрд░ рд╕реАрдзреЗ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/1295#issuecomment -187404245
ред
рдпрджрд┐ рдЖрдк RPC рд╢реИрд▓реА API рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдк рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ @ antanas-arvasevicius: https://github.com/alm-tools/alm/blob/master/docs/contributing.nYNC.md : рдЧреБрд▓рд╛рдм
рдКрдкрд░ рджрд┐рдП рдЧрдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рддреАрдд рд╣реЛрддреЗ рд╣реИрдВ:
string
"рд╕рднреА рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдвреВрдВрдвреЗрдВ" -able рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рди рд╣реА рд░реАрдкреЗрдХреНрдЯреЗрдмрд▓ (рдЬреИрд╕реЗ рдирд╛рдо)редрдпрд╣рд╛рдБ рдПрдХ рдФрд░ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдЬреЛ рд╕реА # рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкреЗрдбрд╝реЛрдВ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдореЛрдЯрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реЛрдЪрд╛-рд╕рдордЭрд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ! рд╕рд┐рдВрдЯреЗрдХреНрд╕ рднрдпрд╛рдирдХ рд╣реИред рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдХрд┐рд╕реА рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд╛рд░ рд╣реИрдВред
рдЪрд▓реЛ рдЗрд╕реЗ type Expr<T, U> = string
ред
рдЬрд╣рд╛рдБ T
рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд╕реНрддреБ рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ U
рдкрд░рд┐рдгрд╛рдо рдкреНрд░рдХрд╛рд░ рд╣реИред
рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдо рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ Expr<T,U>
рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрддрд╛ рд╣реИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ T
рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдЙрд╕ рдкрд░ рдПрдХ рд╕рджрд╕реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: person => person.address.city
ред
рдЬрдм рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреВрд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдЬреЛ рднреА рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ: "address.city"
ред
рдЖрдк рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд╕рд╛рджреЗ рддрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ Expr<any, any>
рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрд╣ рд╡рд┐рд╢реЗрд╖ Expr
рднрд╛рд╖рд╛ рдореЗрдВ
function pluck<T, U>(array: T[], prop: Expr<T, U>): U[];
let numbers = pluck([{x: 1}, {x: 2}], p => p.x); // number[]
// compiles to:
// let numbers = pluck([..], "x");
рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ C # рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реАрдорд┐рдд рд░реВрдк рд╣реИред
рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░рд┐рд╖реНрдХреГрдд рдФрд░ рдХрд╣реАрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?
@fdecampredon @RyanCavanaugh
_ ( @ jods4 - рдореБрдЭреЗ рдЦреЗрдж рд╣реИ рдХрд┐ рдореИрдВ рдпрд╣рд╛рдВ рдЖрдкрдХреЗ рд╕реБрдЭрд╛рд╡ рдХрд╛ рдЬрд╡рд╛рдм рдирд╣реАрдВ рджреЗ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ 'рджрдлрди' рдирд╣реАрдВ рд╣реЛрдЧрд╛ред _
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдлреАрдЪрд░ ('рдЯрд╛рдЗрдк рдкреНрд░реЙрдкрд░реНрдЯреА рдЯрд╛рдЗрдк') рдХрд╛ рдирд╛рдордХрд░рдг рдмрд╣реБрдд рднреНрд░рд╛рдордХ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рдордЭрдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдХрдард┐рди рдерд╛ рдХрд┐ рдпрд╣рд╛рдБ рд╡рд░реНрдгрд┐рдд рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдкрд╣рд▓реА рдЬрдЧрд╣ рдореЗрдВ рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдЕрд░реНрде рд╣реИ!
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЧреБрдг рдирд╣реАрдВ рд╣реИрдВ! undefined
рдФрд░ null
(рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпреЗ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдХреЗрд╡рд▓ рд╣рд╛рд▓рд┐рдпрд╛ рдЬреЛрдбрд╝ рдирд╣реАрдВ рд╣реИрдВ)ред рдЖрджрд┐рдо number
, string
, boolean
рд╢рд╛рдпрдж рд╣реА рдХрднреА рдПрдХ рд╕рдВрдкрддреНрддрд┐ (рдЬреИрд╕реЗ 2 ["рдкреНрд░реЛрдк") рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд рд╣реЛрддреЗ рд╣реИрдВ? рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдПрдХ рдЧрд▓рддреА рд╣реИ)
рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдирд╛рдо рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рдХрд╛рд░ рд╕рдВрджрд░реНрдн рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ред рдпрд╣рд╛рдВ рд╡рд┐рд╖рдп рдПрдХ рдирдП 'рдкреНрд░рдХрд╛рд░' рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡реЗрд░рд┐рдПрдмрд▓ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдореМрдЬреВрджрд╛ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рдЦрд╛рд╕ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореВрд▓реНрдп _must рд╕рдВрдХрд▓рди рд╕рдордп_ рдкрд░ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрд╣ рдЕрддреНрдпрдзрд┐рдХ рд▓рд╛рднрдХрд╛рд░реА рд╣реЛрддрд╛ рдпрджрд┐ рдЗрд╕реЗ рд╡рд┐рд╢реЗрд╖ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рдмрд╛рд╣рд░ рд╡рд░реНрдгрд┐рдд рдФрд░ рд╕рд░рд▓ рд░реВрдк рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛:
interface MyInterface {
prop1: number;
prop2: string;
}
let prop1Name = "prop1";
type Prop1Type = MyInterface[prop1Name]; // Prop1Type is now 'number'
let prop2Name = "prop2";
type Prop2Type = MyInterface[prop2Name]; // Prop2Type is now 'string'
let prop3Name = "prop3";
type NonExistingPropType = MyInterface[prop3Name]; // Compilation error: property 'prop3' does not exist on 'MyInterface'.
let randomString = createRandomString();
type NotAvailablePropType = MyInterface[randomString]; // Compilation error: value of 'randomString' is not known at compile time.
_Edit: рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдпрд╣ рдкрддрд╛
_Edit 2: рд╢рд╛рдпрдж рдпрд╣ рдХреЗрд╡рд▓ const
рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдЬрдм рдПрдХ рдЪрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛? _
рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореВрд▓ рдЙрджреНрджреЗрд╢реНрдп рдХреЗрд╡рд▓ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рдмрд╣реБрдд рд╣реА рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рд╡рд┐рдзрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИ? рдЬреИрд╕реЗ
function func(someString: string): MyInterface[someString] {
..
}
let x = func("prop"); // x gets the type of MyInterface.prop
рдХреНрдпрд╛ рдореИрдВрдиреЗ рдЗрд╕реЗ рдореВрд▓ рд░реВрдк рд╕реЗ рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдкрд░реЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд┐рдпрд╛ рд╣реИ?
рдпрд╣ рдПрдХ рдРрд╕реЗ рдорд╛рдорд▓реЗ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓реЗрдЧрд╛ рдЬрд╣рд╛рдВ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдирд╣реАрдВ рд╣реИ, рдЕрд░реНрдерд╛рдд рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ? рдЬреИрд╕реЗ
let x = func(getRandomString()); // What type if inferred for 'x' here?
рдХреНрдпрд╛ рдпрд╣ рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреА, рдпрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ any
рд╢рд╛рдпрдж рд╣реЛрдЧрд╛?
(рдкреБрдирд╢реНрдЪ: рдпрджрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд░рд╛рджрд╛ рдерд╛, рддреЛ рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХрд╛ рдирд╛рдо рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрдЭрд╛рд╡ рджреВрдВрдЧрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рдХрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╕рдВрджрд░реНрдн рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рд╡рд┐рдзрд┐ рддрд░реНрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ - рдЬрд┐рддрдирд╛ рд▓рдВрдмрд╛ рдпрд╣ рдирд┐рдХрд▓рд╛, рдпрд╣ рд╡рд░реНрддрдорд╛рди рд╢реАрд░реНрд╖рдХ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рдФрд░ рд╡реНрдпрд╛рдЦреНрдпрд╛рддреНрдордХ рд╣реИред)
рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд) рдЬреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦреЗрдВ, рдЬреЛ:
function awaitObject(obj) {
var result = {};
var wait = Object.keys(obj)
.map(key => obj[key].then(val => result[key] = val));
return Promise.all(wait).then(_ => result)
}
рдЬрдм рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд╕реНрддреБ рдкрд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
var res = awaitObject({a: Promise.resolve(5), b: Promise.resolve("5")})
рдкрд░рд┐рдгрд╛рдо res
рдХрд╛ рдкреНрд░рдХрд╛рд░ {a: number; b: string}
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд╕рд╛рде (@Artazor рджреНрд╡рд╛рд░рд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛) рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реЛрдВрдЧреЗ
awaitObject<p, T[p]>(obj: {...p: Promise<T[p]>}):Promise<{...p: T[p]}>
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдКрдкрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, Promise<...>
^ ^ рдЧрд╛рдпрдм рдерд╛
@ рд╕рдВрднрд╛рд╡рдирд╛
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдХрд╣реАрдВ рднреА рдореБрдЭреЗ рдПрдХ рдЙрдЪрд┐рдд рдФрд░ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдорд┐рд▓рд╛ рд╣реИ рдФрд░ рд╕реНрдкрд╖реНрдЯ рдХрдо рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ рдЬреЛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ _detached_ рд╣реИрдВ рдФрд░ рд╢рдмреНрджрд╛рд░реНрде рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдХрд┐рдирд╛рд░реЗ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛; рдореВрд▓ рд░реВрдк рдореЗрдВ рднреА рдХреБрдЫ:
function func<T extends object>(name: string): T[name] {
...
}
name
рд╕рдВрдХрд▓рд┐рдд рд╕рдордп, рдЕрд╢рдХреНрдд, рдпрд╛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдкрд░ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕реЗ func<MyType>(getRandomString())
, func<MyType>(undefined)
редT
рдПрдХ рдЖрджрд┐рдо рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреИрд╕реЗ number
рдпрд╛ null
редT[name]
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдФрд░ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЕрдЧрд░ name
рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдореЗрдВ рдкреБрди: рдЕрд╕рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рддрд░рд╣ рдЗрд╕рдХрд╛ рдореВрд▓реНрдп рдЕрдм рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдкрд░ рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?T["propName"]
рдпрд╛ T[propName]
рдХрд╛рдо рд╣реЛрдЧрд╛? рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╛ рдЪрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рдмрд┐рдирд╛, рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ - рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ!T[name]
рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рд╕реНрдХреЛрдк рдХреЗ рдмрд╛рд╣рд░ рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗfunction func<T extends object>(name: string, val: T[name]) {
...
}
type A = { abcd: number };
const name = "abcd";
let x: A[name]; // Type of 'x' resolves to 'number'
_7ред рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ typeof
(рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рдмрд╛рдж рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдкрд╣рд▓реЗ рд╣реА рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд╕рд░рд▓ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреА рдХреЛрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ:
function get<T, V>(obj: T, propName: string): V {
return obj[propName];
}
type MyType = { abcd: number };
let x: MyType = { abcd: 12 };
let result = get<MyType, typeof x.abcd>(x, "abcd"); // Type of 'result' is 'number'
рдирд┐рд╖реНрдХрд░реНрд╖ рдореЗрдВ: рдпрд╣рд╛рдВ рдХреЛрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рд╕реНрддрд╛рд╡ рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧ рдХреЗрд╕ рдкреНрд░рджрд░реНрд╢рдиреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИред рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдпрд╣ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЧрдП рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдмреНрдпрд╛рдЬ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдХрд┐ рдпрд╣ рдЙрдирдХреЗ рдорд╛рдирдХреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рдЦреЗрдж рд╣реИ рдХрд┐ рдЕрдЧрд░ рдореИрдВ рдпрд╣рд╛рдВ рдереЛрдбрд╝рд╛ рдХрдареЛрд░ рд▓рдЧ рд╕рдХрддрд╛ рд╣реВрдВ (рдореЗрд░реЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╣реАрдВ), рд▓реЗрдХрд┐рди рдореЗрд░реА рдХреЛрдИ рднреА рдЖрд▓реЛрдЪрдирд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд╣реАрдВ рд╣реИ рдпрд╛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдд рдирд╣реАрдВ рд╣реИред
рдХреНрдпрд╛ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрдЯрд╛-рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрд╕ рджреВрд░ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
JS рдПрдХ рдЧрддрд┐рд╢реАрд▓ рднрд╛рд╖рд╛ рд╣реИ, рдХреЛрдб рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдордирдорд╛рдиреЗ рддрд░реАрдХреЗ рд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИред
рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╣рдо рдЬреЛ рдореЙрдбрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЙрд╕рдХреА рд╕реАрдорд╛рдПрдВ рд╣реИрдВ рдФрд░ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдЯреАрдПрд╕ рдореЗрдВ рдореЙрдбрд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред
рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ: рдпрд╣ рдХрд╣рд╛рдБ рддрдХ рдЙрдЪрд┐рдд рдФрд░ рдЙрдкрдпреЛрдЧреА рд╣реИ?
@Spion рд╕реЗ рдЕрдВрддрд┐рдо рдЙрджрд╛рд╣рд░рдг ( awaitObject
) рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╣реИ:
BTW @spion рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рд╕рд╣реА рдирд╣реАрдВ рдорд┐рд▓рд╛ ... рдпрд╣ рдПрдХ Promise
рд░рд┐рдЯрд░реНрди рджреЗрддрд╛ рд╣реИред
рд╣рдо рдореВрд▓ рдореБрджреНрджреЗ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИрдВ, рдЬреЛ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдПрдкреАрдЖрдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдерд╛, рдЬреЛ рдХрд┐ _.pluck
рдЬреИрд╕реЗ рдлрд╝реАрд▓реНрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реЗрддреЗ рд╣реИрдВ
рд╡реЗ API _should be_ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ рдФрд░ рд╡реЗ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИрдВред рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП { ...p: T[p] }
рдЬреИрд╕реЗ рдореЗрдЯрд╛-рдореЙрдбрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдУрдкреА рдореЗрдВ рдХрдИ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ, рдиреЗрдордлреНрд▓реЛ рдореБрджреНрджреЗ рдореЗрдВ
рдПрдХ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЙрди рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдКрдкрд░ рдореЗрд░реА рдЯрд┐рдкреНрдкрдгреА рджреЗрдЦреЗрдВред
@ jods4 рдЗрд╕рдХреА рд╕рдВрдХреАрд░реНрдг рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдореЙрдбрд▓рд┐рдВрдЧ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИред рдореИрдВ рдХрд╣реВрдБрдЧрд╛ рдХрд┐ TS рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдмрдбрд╝реЗ рдЧрд╛рдпрдм рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХред @Artazor https://github.com/Microsoft/TypeScript/issues/1295#issuecomment -177287714 рдКрдкрд░ рджрд┐рдП рдЧрдП рд╕рд░рд▓ рд╕рд╛рдорд╛рди рд╕реЗ рдКрдкрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ, sql рдХреНрд╡реЗрд░реА рдмрд┐рд▓реНрдбрд░ - рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдФрд░ рдЗрд╕реА рддрд░рд╣ред
рдпрд╣ рдмреНрд▓реВрдмрд░реНрдб рдореЗрдВ awaitObject
ред рдЗрд╕рдХреА рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд┐рдзрд┐ рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдмреЗрдХрд╛рд░ рд╣реИред
рдПрдХ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдзрд╛рди рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ред рдпрд╣ рд╕рд░рд▓ рдФрд░ рдЬрдЯрд┐рд▓ рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдЖрдзреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдПрдХ рдХрдордЬрд╝реЛрд░ рд╕рдорд╛рдзрд╛рди рдкрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдиреБрдХреВрд▓рддрд╛ рдХреА рд╕рдорд╕реНрдпрд╛ рдкреИрджрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдпрджрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдПрдХ рдХреЛ рдЕрдкрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред
рд╣рд╛рдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @Artazor рдиреЗ рдЙрди рд╕рднреА рдкрд╣рд▓реБрдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдЕрдиреНрд╡реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдХрд╛рдо рдХрд┐рдпрд╛, рдЬреЛ рд╣рдордиреЗ рдкрд╣рд▓реЗ рдирд╣реАрдВ рд╕реЛрдЪрд╛ рдерд╛ред рдореИрдВ рдирд╣реАрдВ рд░рд╣реВрдБрдЧрд╛ рдХрд┐ рд╣рдо рдореВрд▓ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рднрдЯрдХ рдЧрдП рд╣реИрдВ, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЗрд╕рдХреА рдмреЗрд╣рддрд░ рд╕рдордЭ рд╣реИред
рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдмреЗрд╣рддрд░ рдирд╛рдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпреЗ рдЪреАрдЬреЗрдВ рдЖрдорддреМрд░ рдкрд░ рд╕рд╣реА рдирд╣реАрдВ рд▓рдЧрддреА рд╣реИрдВред "рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЗрдирд░рд┐рдХ" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?
@ рд╕реНрдерд╛рди , рдХреЗрд╡рд▓
awaitObject<p,T[p]>(obj: {...p:Promise<T[p]>}): Promise<{...p:T[p]}>
(рдЖрдкрдиреЗ рдЖрдЙрдЯрдкреБрдЯ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдореЗрдВ рдПрдХ рдкреНрд░реЙрдорд┐рд╕ рдорд┐рд╕ рдХрд┐рдпрд╛ рд╣реИ)
-)
@ jods4 , рдореИрдВ @spion рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреА рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ рдЬрд╣рд╛рдВ { ...p: T[p] }
рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИред рдХрд┐рд╕реА рдПрдХ рдХрд╛ рдирд╛рдо: рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ + рдкреНрд░рд╡рд╛рд╣ / redux
@spion @Artazor
рдореБрдЭреЗ рдмрд╕ рдЪрд┐рдВрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╣реЛ рд░рд╣реА рд╣реИред
рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдкреАрдЫреЗ рдХреА рдкреНрд░реЗрд░рдгрд╛ рдмрд╣ рдЧрдИ рд╣реИред рдореВрд▓ рд░реВрдк рд╕реЗ рдпрд╣ рдПрдкреАрдЖрдИ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдерд╛ рдЬреЛ рдПрдХ рд╡рд╕реНрддреБ рдХреНрд╖реЗрддреНрд░ рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдЕрдм рдпрд╣ рдЬреНрдпрд╛рджрд╛рддрд░ рдПрдкреАрдЖрдИ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирдХреНрд╢реЗ рдпрд╛ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░рддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рд╣рдо рдПрдХ рдкрддреНрдерд░ рд╕реЗ рджреЛ рдкрдХреНрд╖рд┐рдпреЛрдВ рдХреЛ рдорд╛рд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣реВрдВред
рдЕрдЧрд░ рд╣рдо APIs рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рд╕рдорд╕реНрдпрд╛ рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ T[p]
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ (рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХреНрдпреЛрдВ рдХрд╣рд╛)ред
рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП _Just_ awaitObject
рдХреЛ рдЧреИрд░-рд╡рд╛рджрд╛ рдЧреБрдгреЛрдВ рдХреЛ рднреА рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХрдо рд╕реЗ рдХрдо Bluebird props
рдХрд░рддрд╛ рд╣реИред рддреЛ рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ:
awaitObject<p,T[p]>(obj: { ...p: T[p] | Promise<T[p]> }): Promise<T>
рдореИрдВрдиреЗ рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЛ Promise<T>
рдмрджрд▓ рджрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЕрдВрдХрди рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рдЕрдиреНрдп рдЕрддрд┐рднрд╛рд░ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рджрд╛ рдХрд░рддрд╛ рд╣реИ (рдЗрд╕рдХрд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдФрд░ рднреА рдордЬреЗрджрд╛рд░ рд╣реИ)ред рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ { ...p }
рдиреЛрдЯреЗрд╢рди рдХреЛ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдЦрд░рд╛рдм рдореИрдЪ рдорд╛рдирд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЗрди рд╕рднреА рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдХрдард┐рди рдХрд╛рдо рд╣реИред рдЕрдЧрд░ рдЖрдк рдЗрд╕реЗ рдЖрдЧреЗ рдмрдврд╝рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдЕрдЧрд▓рд╛ рдХрджрдо рд╣реИред
@spion @ jods4
рдореИрдВ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЬреЗрдирд░рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ рдФрд░ рди рд╣реА рдЙрдЪреНрдЪ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╣реБрд░реВрдкреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдпреБрдХреНрдд рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИ (рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рдХреБрдЫ "рдЙрдиреНрдирдд" рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде), рдЬреЛ рдЕрд╡рдзрд╛рд░рдгрд╛ рдореЗрдВ typeof
рд╕реЗ рджреВрд░ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг:
type MyType = { abcd: number };
let y: MyType["abcd"]; // Technically this could also be written as MyType.abcd
рдЕрдм рдЗрд╕рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ:
type MyType = { abcd: number };
let x: MyType;
let y: typeof x.abcd;
typeof
рд╕рд╛рде рджреЛ рдореБрдЦреНрдп рдЕрдВрддрд░ рд╣реИрдВред typeof
рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдЯрд╛рдЗрдк (рдХрдо рд╕реЗ рдХрдо рдЧреИрд░-рдЖрджрд┐рдо рд▓реЛрдЧреЛрдВ, рдПрдХ рддрдереНрдп рдЬреЛ рдЕрдХреНрд╕рд░ рдпрд╣рд╛рдВ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ (рдФрд░ рдпрд╣ рдПрдХ рдкреНрд░рдореБрдЦ рдмрд╛рдд рд╣реИ) рдЗрд╕реЗ рд╢рд╛рдмреНрджрд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдерд┐рд░рд╛рдВрдХ (рдЬрд┐рд╕реЗ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЬреНрдЮрд╛рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП) рдХреЛ рд╕рдВрдкрддреНрддрд┐ рдкрде рд╡рд┐рд╡рд░рдгрдХ, рдФрд░ рдЬреЗрдирд░рд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:
const propName = "abcd";
let y: MyType[propName];
// Or with a generic parameter:
let y: T[propName];
рд╣рд╛рд▓рд╛рдБрдХрд┐ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ typeof
рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХреЛрдВ рдХреЗ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ (рдЗрд╕рдореЗрдВ рд╡рд╣ рдорд╛рдорд▓рд╛ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд╣рд╛рдБ x
рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рд╣реИ):
let x: MyType;
const propName = "abcd";
let y: typeof x[propName];
рдФрд░ рдЗрд╕ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдЫ рд▓рдХреНрд╖реНрдп рдорд╛рдорд▓реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
function get<T>(propName: string, obj: T): typeof obj[propName]
typeof
рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХреЗ рд╕реНрддрд░ рдХреА рдЕрдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:
let y: typeof x.prop.childProp.deeperChildProp
рдФрд░ рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╕реНрддрд░ рдкрд░ рдЬрд╛рддрд╛ рд╣реИред Ie рдиреЗ рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдирд╛рдИ рд╣реИ (рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореБрдЭреЗ рдкрддрд╛ рд╣реИ) рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
let y: MyType["prop"]["childProp"]["deeperChildProp"];
// Or alternatively
let y: MyType["prop.childProp.deeperChildProp"];
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рджрд╛рдпрд░рд╛ (рдпрджрд┐ рдЗрд╕реЗ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд╕реНрддрд░ рдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡ рднреА рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ) рдмрд╣реБрдд рд╕рдВрдХреАрд░реНрдг рд╣реИред рдпрд╣ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ), рдЬреЛ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЛ рдЗрд╕реЗ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрддреНрд╕реБрдХ рдмрдирд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рднрд╛рд╖рд╛ рд╕реЗ рдореВрд▓реНрдпрд╡рд╛рди рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХрд╛ рднреА рдЙрдкрднреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред рдПрдХ рд╡реНрдпрд╛рдкрдХ рдпреЛрдЬрдирд╛ рдФрд░ рдбрд┐рдЬрд╛рдЗрди-рдЙрдиреНрдореБрдЦ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдмрд┐рдирд╛, рдпрд╣ рдЬрд▓реНрджрдмрд╛рдЬреА рдореЗрдВ рдХреБрдЫ рдРрд╕рд╛ рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╛рд╕рдордЭ рд▓рдЧрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕ рддрд╛рд░реАрдЦ рдХреЛ рднреА рд╕реНрдкрд╖реНрдЯ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдирд╣реАрдВ рд╣реИред
_Edits: рдХреЛрдб рдореЗрдВ рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рд╕рд╣реА рдХрд┐рдпрд╛ example_
рдореИрдВрдиреЗ typeof
рд╡рд┐рдХрд▓реНрдк рдкрд░ рдереЛрдбрд╝рд╛ рд╢реЛрдз рдХрд┐рдпрд╛ рд╣реИ:
typeof x["abcd"]
рдФрд░ typeof x[42]
рд▓рд┐рдП рднрд╡рд┐рд╖реНрдп рдХреА рднрд╛рд╖рд╛ рдХрд╛ рд╕рдорд░реНрдерди рд╕реНрд╡реАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рдФрд░ рдЕрдм # 6606 рдХреЗ рдЕрдВрддрд░реНрдЧрдд рдЖрддрд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЕрдзреАрди рд╣реИ (рдПрдХ рдХрд╛рд░реНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ)ред
рдпрд╣ рдЖрдзрд╛ рд░рд╛рд╕реНрддрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрдирдХреА рдЬрдЧрд╣ рдкрд░, рдмрд╛рдХреА рдХрдИ рдЪрд░рдгреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
(1) рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рд╕реНрдерд┐рд░рд╛рдВрдХ (рдпрд╛ рд╕рдордХрд╛рд▓рд┐рдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВ - рдЯреБрдкрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?) рдкреНрд░рдХрд╛рд░ рдХреЗ рднрд╛рд╡реЛрдВ рдореЗрдВ рдЧреБрдг рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ, рдЬреИрд╕реЗ:
let x: MyType;
const propName = "abcd";
let y: typeof x[propName];
(2) рдЗрди рд╕реНрдкреЗрд╕рд░реЛрдВ рдХреЛ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ
let x: T; // Where T should extend 'object'
const propName = "abcd";
let y: typeof x[propName];
(3) рдЗрди рд╡рд┐рдирд┐рд░реНрджреЗрд╢рдХреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ, рдФрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ "рддрд░реНрдХреЛрдВ" рдХреЛ рд╕рдВрджрд░реНрдн рддрд░реНрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ( typeof list[0]
рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдЬреИрд╕реЗ pluck
рдХреЛ рдХрд╡рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
function get<T extends object>(obj: T, propertyName: string): typeof obj[propertyName];
function pluck<T extends object>(list: Array<T>, propertyName: string): Array<typeof list[0][propertyName]>;
( object
рдкреНрд░рдХрд╛рд░ рдпрд╣рд╛рдБ # 1809 рдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИ)
рдпрджреНрдпрдкрд┐ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА (рдЬреИрд╕реЗ typeof obj[propName][nestedPropName]
рд╕рдорд░реНрдерди рдХрд░ рд╕рдХрддрд╛ рд╣реИ) рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдпрд╣ рд╡реИрдХрд▓реНрдкрд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдпрд╣рд╛рдВ рд╡рд░реНрдгрд┐рдд рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЛ рдХрд╡рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдРрд╕реЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬреЛ рдЗрд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ (рдПрдХ рдкрд░рд┐рджреГрд╢реНрдп рдЬреЛ рдорди рдореЗрдВ рдЖрддрд╛ рд╣реИ рд╡рд╣ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдЙрджрд╛рд╣рд░рдг рдмрд┐рд▓реНрдХреБрд▓ рднреА рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рдорд╛рдорд▓реЗ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ)ред
_Edits: code_ рдореЗрдВ рдХреБрдЫ рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рд╕реБрдзрд╛рд░рд╛
@ рдорд╛рд▓рд┐рдмреБрдЬрд╝рд┐рдпреЛрд╕
рдХреБрдЫ рд╡рд┐рдЪрд╛рд░:
nameof
рдпрд╛ Expression
ред.d.ts
рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЖрдо рддреМрд░ рдкрд░ TS рдХрд╛рд░реНрдпреЛрдВ / рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдореЗрдВ рд╡реИрдзрд╛рдирд┐рдХ рд░реВрдк рд╕реЗ рдХрдордЬреЛрд░ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рддреНрдпрд╛рдкрди рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛редрдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрддрд╛ рд╣реВрдВ, рдЙрддрдирд╛ рдЕрдзрд┐рдХ Expression<T, U>
рдЙрд╕ рддрд░рд╣ рдХреЗ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдзрд╛рди рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИред рдпрд╣ рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдареАрдХ рдХрд░рддрд╛ рд╣реИ, рдкрд░рд┐рдгрд╛рдо рдХреА рдЯрд╛рдЗрдкрд┐рдВрдЧ рдФрд░ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдмрд╛рдВрдЭ + рд╕рддреНрдпрд╛рдкрди рдпреЛрдЧреНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
@ jods4
рдЖрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рддрд░реАрдХреЗ рдореЗрдВ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ pluck
рдХреЛ рднрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджреНрдпрдкрд┐ рдореИрдВрдиреЗ C # рд╕реЗ рдмрд╣реБрдд рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛, рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдХреЗ рд╕рд╛рде рдХрднреА рдкреНрд░рдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдЙрдирдХреА рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╕рдордЭ рдирд╣реАрдВ рд╣реИред
рд╡реИрд╕реЗ рднреА, рд╕рд┐рд░реНрдл рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЯрд╛рдЗрдк рдЯрд╛рдЗрдк рддрд░реНрдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ pluck
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдХреЛрдИ рднреА map
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╡рд╣реА рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА ( рдпрд╣ рдЕрдиреБрдорд╛рди рд╣реИ) рдФрд░ рдпрд╣ рднреА рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдФрд░ рдкреВрд░реНрдгрддрд╛ рджреЗрдЧрд╛:
let x = [{name: "John", age: 34}, {name: "Mary", age: 53}];
let result = x.map(obj => obj.name);
// 'result' is ["John", "Mary"] and its type inferred as 'string[]'
рдЬрд╣рд╛рдБ map
(рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдзрд┐рдХ рд╕рд░рд▓реАрдХреГрдд) рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
map<U>(mapFunc: (value: T) => U): U[];
рдПрдХ рд╣реА рд▓реИрдВрдмрдбрд╛ рдХреЗ рдХрд┐рд╕реА рднреА рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдЪрд╛рд▓рди рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ 'рдЯреНрд░рд┐рдХ' рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЬрд┐рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ) рдФрд░ рдЗрд╕рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЛ рдЗрд╕рдореЗрдВ рд╕реЗрдЯ рдХрд░реЗрдВ:
function thisIsATrick<T, U>(obj: T, onlyPassedToInferTheReturnType: () => U): U {
return;
}
let x = {name: "John", age: 34};
let result = thisIsATrick(x, () => x.age) // Result inferred as 'number'
_Edit: рдпрд╣ рдпрд╣рд╛рдБ рдПрдХ рдореЗрдордиреЗ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рди рдХреЗрд╡рд▓ рдЦреБрдж рдмрд╛рдд! рд╣рд╛рд▓рд╛рдВрдХрд┐ рдиреЗрд╕реНрдЯреЗрдб рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ (рдЬреИрд╕реЗ x.prop.Childprop
) рдЬреИрд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдпрд╛ рдЕрд╢рдХреНрдд рд╕рдВрджрд░реНрдн рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕реЗ рд▓рдВрдмреЛрджрд░ рдореЗрдВ рд░рдЦрдирд╛, рдЬрд┐рд╕реЗ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ рдмрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ ред_
рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдБ рдХрд┐ рдореИрдВ рдпрд╣рд╛рдБ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рд╕реЗ рдмрд╣реБрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдБред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореБрдЭреЗ рдХрднреА рднреА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рд╣реБрдИ рдЬреЛ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдирд╛рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИред рдкреНрд░рдХрд╛рд░ рддрд░реНрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ (рдЬрд╣рд╛рдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдлрд╛рдпрджреЗ рднреА рд╣реИрдВ) рдкрд╛рд╕ рдХрд░рдирд╛ рдЖрдорддреМрд░ рдкрд░ рдХрдИ рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
рдЬрд┐рд╕ рдХрд╛рд░рдг рд╕реЗ рдореИрдВрдиреЗ typeof
рд╡реИрдХрд▓реНрдкрд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдерд╛, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдорд╛рди рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЬреЛ рд▓реЛрдЧ рдпрд╣рд╛рдВ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдореИрдВ рдЦреБрдж рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реВрдВрдЧрд╛? рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛, рдХрднреА рднреА рдЗрд╕рдХреА рдЬрд╝рд░реВрд░рдд рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рд╣реБрдИ (рдпрд╣ рдмрд╕ рдЗрддрдирд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рд▓рдЧрднрдЧ рдХрднреА рднреА рдмрд╛рд╣рд░реА рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ рдЬреИрд╕реЗ рдХрд┐ рдЕрдВрдбрд░рд╕реНрдХреЛрд░, рдореИрдВ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рдЖрдзрд╛рд░ рдкрд░ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ)ред
@malibuzios рд╕рдЪ рд╣реИ, pluck
рд▓рдВрдмреЛрджрд╛ + map
рдЕрдм рдмрд┐рд▓реНрдЯ-рдЗрди рдХреЗ рд╕рд╛рде рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд╣реИред
рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдореИрдВ 5 рдЕрд▓рдЧ-рдЕрд▓рдЧ рдПрдкреАрдЖрдИ рджреЗрддрд╛ рд╣реВрдВ рдЬреЛ рд╕рднреА рддрд╛рд░ рд▓реЗрддреЗ рд╣реИрдВ - рд╡реЗ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВред
@ jods4 рдФрд░ рдЕрдиреНрдп
рдХреЗрд╡рд▓ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдЬрдм # 6606 рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдЪрд░рдг 1 рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ (рд╕рдВрдкрддреНрддрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧрд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░рдВрддрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ) рдпрд╣рд╛рдВ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореЗрдВ рд╕реЗ рдХреБрдЫ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЙрддрдиреЗ рд╣реА рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдврдВрдЧ рд╕реЗ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ) рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдирд╛рдо рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг)ред
function observeProperty<T, U>(obj: T, propName: string ): Subscriber<U> {
....
}
let x = { name: "John", age: 42 };
const propName = "age";
observeProperty<typeof x, typeof x[propName]>(x, propName);
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕ рдХреА рдорд╛рддреНрд░рд╛ рдЪрд░рдг 2 рдФрд░ 3 рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдХрдо рд╣реЛ рд╕рдХрддреА рд╣реИ (рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ 1 рдкрд╣рд▓реЗ рд╕реЗ рд╣реА # 6606 рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛ)ред рдЪрд░рдг 2 рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЙрд╕ рдорд╛рдорд▓реЗ рдХреЛ рднреА рдХрд╡рд░ рдХрд░реЗрдЧрд╛ рдЬрд╣рд╛рдВ x
рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рд╣реИ (рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?)ред
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдХрд╛рд░рдг рдХрд┐ рдореИрдВрдиреЗ рдПрдХ рдмрд╛рд╣рд░реА рд╕реНрдерд┐рд░рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рди рдХреЗрд╡рд▓ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЛ рджреЛ рдмрд╛рд░ рд▓рд┐рдЦрд╛ рд╣реИ рди рдХреЗрд╡рд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд▓реНрдХрд┐ рдпрд╣ рднреА рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдирд╛рдо рд╣рдореЗрд╢рд╛ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЕрднреА рднреА "рдирд╛рдо рдмрджрд▓реЗрдВ" рдФрд░ "рд╕рднреА рдЦреЛрдЬреЗрдВ" рдЬреИрд╕реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рд╕рдВрджрд░реНрдн ", рдЬреЛ рдореБрдЭреЗ рдПрдХ рдЧрдВрднреАрд░ рдиреБрдХрд╕рд╛рди рд▓рдЧрддрд╛ рд╣реИред
@ jods4 рдореИрдВ рдЕрднреА рднреА рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдХрд┐ nameof
рдФрд░ рдЗрд╕рдХреЗ рд╡реЗрд░рд┐рдПрдВрдЯ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рдПрдХ рдФрд░ рд╡рд┐рдЪрд╛рд░ рд╣реИред
рдЪреВрдВрдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ, рдЬреИрд╕реЗ рдХреЛрдИ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
let x: "HELLO";
рдХреЛрдИ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рд╢рд╛рдмреНрджрд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реИ
(_Edit: рдЗрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ s
рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдореЗрдВ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИ, рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдкрджреЛрдВ рдкрд░ const
рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ ( readonly
рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ) рд╣рд╛рд▓рд╛рдВрдХрд┐)ред_) :
function func(const s: string)
string
s
рд╕рд╛рде рдЬреБрдбрд╝реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рдпрд╣рд╛рдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЬреЗрдиреЗрд░рд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд▓рд┐рдЦреВрдВрдЧрд╛ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ):
function func<S extends string>(const s: S)
func("TEST");
рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
function func(s: "TEST")
рдФрд░ рдЕрдм рдЗрд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХреЛ "рдкрд╛рд╕" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рддрд░реАрдХреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдХреЛ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИред
function observeProperty<T, S extends string>(obj: T, const propName: S): Subscriber<T[S]>
x = { name: "John", age: 33};
observeProperty(x, nameof(x.age))
рдЪреВрдБрдХрд┐ T[S]
, рджреЛрдиреЛрдВ T
, рдФрд░ S
рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВред рд░рди-рдЯрд╛рдЗрдо рдФрд░ рдЯрд╛рдЗрдк рд╕реНрдХреЛрдк рдПрд▓рд┐рдореЗрдВрдЯреНрд╕ (рдЬреИрд╕реЗ T[someString]
) рдХреЛ рдорд┐рдХреНрд╕ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдВрдпреБрдХреНрдд рд╣реЛрдирд╛ рдЕрдзрд┐рдХ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реИред
_Edits: рдПрдХ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг ред_
рдЪреВрдВрдХрд┐ рдореИрдВ TS 1.8.7
рдФрд░ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЗрд╕ рдмрд╛рдд рдХреА рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рдереА рдХрд┐ рд╣рд╛рд▓ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ
const x = "Hello";
x
рдХрд╛ рдкреНрд░рдХрд╛рд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ "Hello"
, (рдпрд╛рдиреА: x: "Hello"
) рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рд╣реИ, рдЬреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ (# 6554 рджреЗрдЦреЗрдВ)ред
рддреЛ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдЧрд░ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ const
(рдпрд╛ рд╢рд╛рдпрдж readonly
рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛?) рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдерд╛:?
function func<S extends string>(const s: S): S
рдлрд┐рд░ рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдпрд╣ рдкрдХрдбрд╝ рд╕рдХрддрд╛ рд╣реИ:
let result = func("abcd"); // type of 'result' inferred as the literal type "abcd"
рдЪреВрдВрдХрд┐ рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдирдпрд╛ рд╣реИ рдФрд░ рд╣рд╛рд▓ рдХреА рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛:
(1) рдЬрдм const
(рдФрд░ рд╢рд╛рдпрдж readonly
рд░реВрдк рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ?) рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЪрд░ рдХрд╛ рдПрдХ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕рдВрдХрд▓рди-рд╕рдордп рдкрд░ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЪрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╕рдорд╛рди рдореВрд▓реНрдп рд╣реЛрддрд╛ рд╣реИ ( рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╣рд╛рд▓рд┐рдпрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ рдЬреЛ 1.8.x
) рдкрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдЙрджрд╛
const x = "ABCD";
рдХреЗ рдкреНрд░рдХрд╛рд░ x
рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рди рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ "ABCD"
, рдирд╣реАрдВ string
!, рдЬреИрд╕реЗ рдПрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рд░рд╛рдЬреНрдп рд╕рдХрддрд╛ рд╣реИ x: "ABCD"
ред
(реи) рдпрджрд┐ readonly
рдлрд╝рдВрдХреНрд╢рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рдереА, рддреЛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ readonly
рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛ рдЬрдм рдпрд╣ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИ!
function func<S extends string>(readonly str: S);
func("ABCD");
рдпрд╣рд╛рдБ S
рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ "ABCD"
, рдирд╣реАрдВ string
!
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд░ str
рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдирд╣реАрдВ рдерд╛, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдкреБрди: рдЕрд╕рд╛рдЗрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рдЕрдиреБрдорд╛рди рдХреЗрд╡рд▓ string
ред
function func<S extends string>(str: S) {
str = "DCBA"; // This may happen
}
func("ABCD");
(рей) рдЗрд╕рдХрд╛ рд▓рд╛рдн рд▓реЗрдирд╛ рд╕рдВрднрд╡ рд╣реИ рдФрд░ рдореВрд▓ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рдВрджрд░реНрдн рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕реЗ string
to
function get<T extends object, S extends string>(obj: T, readonly propName: S): T[S]
рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯрд╛рдЗрдк рддрд░реНрдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:
let x = { name: "John", age: 42 };
get(x, "age"); // result type is inferred to be 'number'
// or for stronger type safety:
get(x, nameof(x.age)); // result type is inferred to be 'number'
_Edits: рдХреБрдЫ рд╡рд░реНрддрдиреА рдФрд░ рдХреЛрдб рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рд╕реБрдзрд╛рд░ рджрд┐рдпрд╛ ред_
_Note: рдЗрд╕ рд╕рдВрд╢реЛрдзрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдЕрдм # 7730._ рдореЗрдВ рднреА рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
рдпрд╣рд╛рдБ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧ рд╣реИ (рдпрд╛ "рдЕрдиреБрдХреНрд░рдорд┐рдд рдЬреЗрдирд░рд┐рдХ" рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ) рдЬреЛ @Raynos рдХреЗ рд╕рд╛рде рдЪрд░реНрдЪрд╛ рдореЗрдВ рдЖрдпрд╛ рдерд╛
рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рд╕рд╛рдорд╛рдиреНрдп рдЪреЗрдХрд░ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
function tArray<T>(f:(t:any) => t is T) {
return function (a:any): a is Array<T> {
if (!Array.isArray(a)) return false;
for (var k = 0; k < a.length; ++k)
if (!f(a[k])) return false;
return true;
}
}
function tNumber(n:any): n is number {
return typeof n === 'number'
}
var isArrayOfNumber = tArray(tNumber)
function test(x: {}) {
if (isArrayOfNumber(x)) {
return x[x.length - 1].toFixed(2); // this type checks
}
}
рдПрдХ рдмрд╛рд░ рдЬрдм рд╣рдордиреЗ рдЬреЗрдиреЗрд░рд┐рдХ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░ рд▓рд┐рдпрд╛, рддреЛ рд╣рдо рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЪреЗрдХрд░ рднреА рд▓рд┐рдЦ рд╕рдХреЗрдВрдЧреЗ:
function tObject<p, T[p]>(checker: {...p: (t:any) => t is T[p]}) {
return function(obj: any): obj is {...p: T[p] } {
for (var key in checker) if (!checker[key](obj[key])) return false;
return true;
}
}
рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ, рд╕рдВрдЦреНрдпрд╛, рдмреВрд▓рд┐рдпрди, рдЕрд╢рдХреНрдд рдФрд░ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗ рд▓рд┐рдП рдЖрджрд┐рдо рдЪреЗрдХрд░реНрд╕ рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдЖрдкрдХреЛ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЗрдВ рд▓рд┐рдЦрдиреЗ рджреЗрдВрдЧреЗ:
var isTodoList = tObject({
items: tArray(tObject({text: tString, completed: tBoolean})),
showCompleted: tBoolean
})
рдФрд░ рдпрд╣ рд╕рд╣реА рд░рдирдЯрд╛рдЗрдо рдЪреЗрдХрд░ _and_ рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдкреНрд░рдХрд╛рд░ рдЧрд╛рд░реНрдб рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдо рд╣реИ, рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ :)
рдХреНрдпрд╛ рдХрд┐рд╕реА рдиреЗ рдЗрд╕ рдкрд░ рдЕрднреА рддрдХ рдХреЛрдИ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ, рдпрд╛ рдпрд╣ рдХрд┐рд╕реА рдХреЗ рд░рдбрд╛рд░ рдкрд░ рд╣реИ? рдпрд╣ рдПрдХ рдмрдбрд╝рд╛ рд╕реБрдзрд╛рд░ рд╣реЛрдЧрд╛ рдХрд┐ рдХрд┐рддрдиреЗ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ lodash
рдпрд╛ ramda
рдФрд░ рдХрдИ рдбреЗрдЯрд╛рдмреЗрд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд╕рдВрдж рд╣реИрдВред
@malibuzios рдХрд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдЖрдк @Artazor рдХреЗ рд╕реБрдЭрд╛рд╡ рдкрд░ рдкрд╣реБрдБрдЪ рд░рд╣реЗ рд╣реИрдВ :)
рдЕрдкрдиреА рдЪрд┐рдВрддрд╛рдУрдВ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
function func<S extends string>(readonly str: S): T[str] {
...
}
рдпрд╣ рд╣реЛрдЧрд╛
function func<S extends string, T[S]>(str: S):T[S] { }
рдЗрд╕ рддрд░рд╣, рдирд╛рдо рдХреЛ рд╕рдмрд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ (рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдерд┐рд░ рдкреНрд░рдХрд╛рд░) рдХреЗ рд╕рд╛рде рд▓реЙрдХ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрдм рдЗрд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:
func("test")
рдкреНрд░рдХрд╛рд░ S
"test"
( string
) рдмрди рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ str
рдХреЛ рдПрдХ рдЕрд▓рдЧ рдореВрд▓реНрдп рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдЧрд░ рдЖрдкрдиреЗ рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ, рдЬреИрд╕реЗ
str = "other"
рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рдЬрдм рддрдХ рдХрд┐ рд╡рд┐рдЪрд░рдг рдзреНрд╡рдирд┐ рдореБрджреНрджреЗ рдирд╣реАрдВ рд╣реИрдВ;))
рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВ рдПрдХ рдордирдорд╛рдирд╛ рд╕реБрдкрд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред
рддреЛ рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рдирд┐рдореНрди рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЬреЛрдбрд╝рдирд╛ рд╣реИ: рдХреЗрд╡рд▓ T[prop]
рд╣реЛрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВ рд╕рд┐рдВрдЯреИрдХреНрд╕ T[...props]
рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдЬрд╣рд╛рдБ props
рдХреЛ T
рд╕рджрд╕реНрдпреЛрдВ рдХрд╛ рдПрдХ рд╕рд░рдгреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕реБрдкрд░ рдкреНрд░рдХрд╛рд░ рд╣реИ T
рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде T
рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд props
ред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ Sequelize рдореЗрдВ рдЕрддреНрдпрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ - рдиреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп ORM.js. рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛рд░рдгреЛрдВ рдФрд░ рд╕рд╣реА рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХреЗрд╡рд▓ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░рдирд╛ рдмреБрджреНрдзрд┐рдорд╛рди рд╣реИ, рдЬрд┐рдирдХрд╛ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рдЕрдХреНрд╕рд░ рд╕реБрдкрд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛрддрд╛ рд╣реИред
interface IUser {
id: string;
name: string;
email: string;
createdAt: string;
updatedAt: string;
password: string;
// ...
}
interface Options<T> {
attributes: (memberof T)[];
}
interface Model<IInstance> {
findOne(options: Options<IInstance>): IInstance[...options.attributes];
}
declare namespace DbContext {
define<T>(): Model<T>;
}
const Users = DbContext.define<IUser>({
id: { type: DbContext.STRING(50), allowNull: false },
// ...
});
const user = Users.findOne({
attributes: ['id', 'email', 'name'],
where: {
id: 1,
}
});
user.id
user.email
user.name
user.password // error
user.createdAt // error
user.updatedAt // error
(рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЗрд╕рдореЗрдВ рдСрдкрд░реЗрдЯрд░ memberof
, рдЬреЛ рдХрд┐ рдЖрдк рдЗрд╕рд╕реЗ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ options.attributes
рднреА рд╣реИ, рдЬреЛ typeof options.attributes
, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ typeof
рдСрдкрд░реЗрдЯрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдмреЗрдорд╛рдиреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ))ред
рдЕрдЧрд░ рдХреЛрдИ рдЬреЛрд░ рдирд╣реАрдВ рджреЗрддрд╛, рддреЛ рдореИрдВрдиреЗ рдЗрд╕ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред
рдлрдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдЯрд╛рдЗрдк рд╕реЗрдлреНрдЯреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдпрд╛рдиреА рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд░рд┐рдЯрд░реНрди рдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдХрд╛рдо рд╣реЛ?
interface A {
a: string;
}
function f(p: string): A[p] {
return 'aaa'; // This is string, but can we ensure it is the intended A[p] ?
}
рд╕рд╛рде рд╣реА рдпрд╣рд╛рдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ "рдкреНрд░реЙрдкрд░реНрдЯреА рдЯрд╛рдЗрдк" рдирд╛рдо рдереЛрдбрд╝рд╛ рдЧрд▓рдд рд▓рдЧрддрд╛ рд╣реИред рдпрд╣ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВ, рдЬреЛ рд▓рдЧрднрдЧ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВред
"рд╕рдВрдкрддреНрддрд┐ рд╕рдВрджрд░реНрднрд┐рдд рдкреНрд░рдХрд╛рд░" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдЖрдкрдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ
рдореЗрд░рд╛ рд╡рд┐рдЪрд╛рд░ рдордВрдерди:
let a: A;
function f(p: string): A[p] {
let x = a[p]; // typeof A[p], only when:
// 1. p is directly referencing function argument
// 2. function return type is Property Reference Type
p = "abc"; // not allowed to assign a new value when p is used on Property Reference Type
return x; // x is A[p], so okay
}
рдФрд░ рд╡рд╛рдкрд╕реА рд▓рд╛рдЗрди рдкрд░ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред
рдЖрдкрдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд╕рд╛рде @malibuzios рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕рднреА рдЬреЗрдирд░рд┐рдХ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдпрджрд┐ рд╡реЗ рдЕрдиреБрдорд╛рди
Https://github.com/Microsoft/TypeScript/issues/1295#issuecomment -239653337 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ TS рдЯреАрдо рдХреА рдХреЛрдИ рдЯрд┐рдкреНрдкрдгреА?
@RyanCavanaugh @mhegazy рдЖрджрд┐?
рдирд╛рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ (рдХрдо рд╕реЗ рдХрдо рд╡рд╣ рд░реВрдк рдЬреЛ @Artazor рдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛) "рдЕрдиреБрдХреНрд░рдорд┐рдд рдЬреЗрдирд░рд┐рдХ"
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реЗ рдХреЛрдг рд╕реЗ рд╕рдорд╛рдзрд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рд▓рдВрдмрд╛ рдзрд╛рдЧрд╛ рд╣реИред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЬреЗрдиреЗрд░рд┐рдХ рд╕реБрдЭрд╛рд╡ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛, рд╣рдо рдЗрдВрдбреЗрдХреНрд╕реЗрд╢рди рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓рд┐рдЯрд░рд▓реНрд╕ рдХреЛ рдЗрдВрдбреЗрдХреНрд╕рд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрдирдХрд╛ рд╕рдордХрдХреНрд╖ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рд╡реЗ рдЗрд╕ рд╕рдордп рдирд╣реАрдВ рд╣реИрдВ):
interface A1 {
a: number;
b: boolean;
}
interface A2 {
[index: "a"]: number;
[index: "b"]: boolean;
}
рдЗрд╕рд▓рд┐рдП, рд╣рдо рддрдм рд▓рд┐рдЦ рд╕рдХрддреЗ рдереЗ
declare function pluck<P, T extends { [indexer: P]: R; }, R>(obj: T, p: P): R;
рдХреБрдЫ рдмрд╛рддреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
P
рдХреЗрд╡рд▓ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?P extends string
рдмрд╣реБрдд рд╡рд┐рдЪрд╛рд░рдзрд╛рд░рд╛ рдирд╣реАрдВ рд╣реЛрдЧреАP super string
рдмрд╛рдзрд╛ (# 7265, # 6613, https://github.com/Microsoft/TypeScript/issues/6613#issuecomment-175314703) рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реЛ рд░рд╣реА рд╣реИT
рдореЗрдВ string
s рдпрд╛ number
s рдХрд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╣реИред рддрдм P
string
рдпрд╛ number
ред"something"
рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ string
рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛрдЧрд╛P
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП{ [i: string]: number /* | undefined */ }
undefined
рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ?P
, T
рдФрд░ R
рдХреЗ рдмреАрдЪ рд╕рднреА рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирд┐рд╖реНрдХрд░реНрд╖ рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреБрдВрдЬреА рд╣реИ@weswigham @mhegazy , рдФрд░ рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ; рд╣рдо рдЖрдкрдХреЛ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдП рдЬрд╛ рд░рд╣реЗ рдХрд┐рд╕реА рднреА рдШрдЯрдирд╛рдХреНрд░рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВрдЧреЗ, рдФрд░ рдпрд╣ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рд╡рд┐рдЪрд╛рд░ рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╣реИред
рд╡рд░реНрддрдорд╛рди рд╡рд┐рдЪрд╛рд░:
keysof Foo
рдСрдкрд░реЗрдЯрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ Foo
рд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдореЛрдВ рдХреА рдпреВрдирд┐рдпрди рдХреЛ рд╣рдерд┐рдпрд╛рдиреЗ рдХреЗ рд▓рд┐рдПредFoo[K]
рдкреНрд░рдХрд╛рд░ рдЬреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ K
рд▓рд┐рдП рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдорд┐рд▓рди рд╣реИредрдЗрди рдмреБрдирд┐рдпрд╛рджреА рдмреНрд▓реЙрдХреЛрдВ рд╕реЗ, рдпрджрд┐ рдЖрдкрдХреЛ рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ
function foo<T, K extends keysof T>(obj: T, key: K): T[K] {
// ...
}
рдпрд╣рд╛рдВ, K
keysof T
рдХрд╛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдШ рд╣реИред рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ key
рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрд╕реЗ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдЙрд╕ рд╢рд╛рдмреНрджрд┐рдХ / рд╢рд╛рдмреНрджрд┐рдХ рд╕рдВрдШ рджреНрд╡рд╛рд░рд╛ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
interface HelloWorld { hello: any; world: any; }
function foo<K extends keysof HelloWorld>(key: K): K {
return key;
}
// 'x' has type '"hello"'
let x = foo("hello");
рд╕рдмрд╕реЗ рдмрдбрд╝рд╛ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ keysof
рдЕрдХреНрд╕рд░ рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ "рджреЗрд░реА" рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдмрд╣реБрдд рдЙрддреНрд╕реБрдХ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдореИрдВрдиреЗ рдЬреЛ рдкрд╣рд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдерд╛ (рдпрд╛рдиреА рдЬрд┐рд╕ рдорд╛рдорд▓реЗ рдХреЛ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрдард┐рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ: рдореБрд╕реНрдХрд╛рди :)ред
рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕рднреА рдХреЛ рдПрдХ рдЕрджреНрдпрддрди рджреЗрддрд╛ рд╣реИред
@DanielRosenwasser рдЕрдкрдбреЗрдЯ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореИрдВрдиреЗ рдЕрднреА рджреЗрдЦрд╛ @weswigham рдиреЗ keysof
рдСрдкрд░реЗрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ PR рд╕рдмрдорд┐рдЯ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рд╢рд╛рдпрдж рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЖрдк рд▓реЛрдЧреЛрдВ рдХреЛ рд╕реМрдВрдкрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред
рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдореВрд▓ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕реЗ рдкреНрд░рд╕реНрдерд╛рди рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рдХреНрдпреЛрдВ рд▓рд┐рдпрд╛?
function get(prop: string): T[prop];
рдФрд░ keysof
рдкрд░рд┐рдЪрдп
T[prop]
рдХрдо рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЗрдВрдЯрд░рд▓реЗрдХреНрдЯреЗрдб рдорд╢реАрдирд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдХ рдмрдбрд╝рд╛ рд╕рд╡рд╛рд▓ рдпрд╣рд╛рдБ рдХреИрд╕реЗ рдЖрдк рднреА рдХрд╛ рд╢рд╛рдмреНрджрд┐рдХ рд╕рд╛рдордЧреНрд░реА рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ prop
рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП T
ред рдореБрдЭреЗ рднреА рдкреВрд░рд╛ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдХрд░реЗрдВрдЧреЗред рдХреНрдпрд╛ рдЖрдк рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝реЗрдВрдЧреЗ? рдХреНрдпрд╛ рдЖрдкрдХреЛ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╡реНрдпрд╡рд╣рд╛рд░ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА? рдХреНрдпрд╛ рдЖрдкрдХреЛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдореЗрдВ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛?
рдЬрд╡рд╛рдм рд╢рд╛рдпрдж рдЙрди рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рд╛рдБ рд╣реИред рдореИрдВрдиреЗ рд╣рдореЗрдВ рдЙрд╕рд╕реЗ рджреВрд░ рдХрд░ рджрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реА рдЖрдВрдд рдиреЗ рдореБрдЭреЗ рдмрддрд╛рдпрд╛ рдХрд┐ рджреЛ рд╕рд░рд▓, рдЕрд▓рдЧ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рдерд╛ред рдирдХрд╛рд░рд╛рддреНрдордХ рдкрдХреНрд╖ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рд╣реИред
рдпрджрд┐ рдирдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИрдВ рдЬреЛ рдЗрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рдХрд┐ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдЙрдирдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдХрдард┐рди рдмрдирд╛ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╢рд╛рдпрдж рд╣рдореЗрдВ рдЙрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ рдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреЛрдЧ-рд╕реНрдерд▓ рд╡рд╣ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рд╡реИрд╕реЗ рднреА рд▓рд╛рдн рдорд┐рд▓рддрд╛ рд╣реИред
@DanielRosenwasser рдмрдореБрд╢реНрдХрд┐рд▓ рдЦрд░рдЧреЛрд╢ рдЫреЗрдж рдиреАрдЪреЗ рдЪрд▓рд╛ рдЧрдпрд╛ред рдореБрдЭреЗ рдЕрднреА рднреА @SaschaNaz рд╡рд┐рдЪрд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ keysof
рдмреЗрдорд╛рдиреА рд╣реИред T[p]
рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдХрд┐ p
рдХреЛ T
рдХреЗ рд╢рд╛рдмреНрджрд┐рдХ рд░рдВрдЧрдордВрдЪ рдХреА рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рд╕реЗ рдПрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдореЗрд░рд╛ рдЦреБрд░рджрд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ PropertyReferencedType
рдирд╛рдордХ рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд░рд┐рдЪрдп рджрд┐рдпрд╛ рдЬрд╛рдПред
export interface PropertyReferencedType extends Type {
property: Symbol;
targetType: ObjectType;
}
рдЬрдм рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреА рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рд╣реИ рдХрд┐ рдХреЗ рд╕рд╛рде рдШреЛрд╖рд┐рдд рдореЗрдВ рдкреНрд░рд╡реЗрд╢ PropertyReferencedType
рдпрд╛ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд┐ рд╕рдВрджрд░реНрдн PropertyReferencedType
: рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ ElementAccessExpression
рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд░реНрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рд╕рдВрджрд░реНрдн рдкрд╣реБрдВрдЪ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдкреНрд░рддреАрдХред
export interface Type {
flags: TypeFlags; // Flags
/* <strong i="20">@internal</strong> */ id: number; // Unique ID
//...
referencedProperty: Symbol; // referenced property
}
рддреЛ рдПрдХ рд╕рдВрджрд░реНрднрд┐рдд рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рддреАрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рдХрд╛рд░ PropertyReferencedType
ред рдЬрд╛рдБрдЪ рдХреЗ рджреМрд░рд╛рди, referencedProperty
рдХреЛ p
T[p]
рдЕрдиреБрд░реВрдк рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдореВрд▓ рддрддреНрд╡ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ T
рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЪреАрдЬреЛрдВ рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП p
рдХреЛ рднреА const рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдирдпрд╛ рдкреНрд░рдХрд╛рд░ PropertyReferencedType
рдХреЗрд╡рд▓ "рдЕрдирд╕реБрд▓рдЭреЗ рдкреНрд░рдХрд╛рд░" рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдореМрдЬреВрдж рд╣реИред рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдкрд░ рдХрд┐рд╕реА рдХреЛ p
рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
interface A { a: string }
declare function getProp(p: string): A[p]
getProp('a'); // string
PropertyReferencedType
рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдЪрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреЙрд▓ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ PropertyReferencedType
рдХреЗрд╡рд▓ рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ T[p]
рд╕рд╛рде рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╢рд░реАрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк keysof
рдФрд░ T[K]
рдкреНрд░рдХрд╛рд░ рдХреЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдЙрдирдХрд╛ рдЗрд╕ рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
interface A {
a: number;
b: string;
}
type AK = keysof A; // "a" | "b"
type AV = A[AK]; // number | string ?
type AA = A["a"]; // number ?
type AB = A["b"]; // string ?
type AC = A["c"]; // error?
type AN = A[number]; // error?
type X1 = keysof { [index: string]: number; }; // string ?
type X2 = keysof { [index: string]: number; [index: number]: string; }; // string | number ?
@DanielRosenwasser рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдореЗрд░реЗ рд╕рд╛рде рд╕рдорд╛рди рдЕрд░реНрде рдирд╣реАрдВ рд╣реЛрдЧрд╛
function foo<T, K extends keysof T>(obj: T, key: K): T[K] {
// ...
}
// same as ?
function foo<K, V, T extends { [k: K]: V; }>(obj: T, key: K): V {
// ...
}
рдореИрдВ рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдХреЗ _.pick
рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреИрд╕реЗ рд▓рд┐рдЦреЗ рдЬрд╛рдПрдВрдЧреЗ:
o2 = _.pick(o1, 'p1', 'p2');
pick(Object, ...props: String[]) : WHAT GOES HERE;
@rtm рдореИрдВрдиреЗ рдЗрд╕реЗ https://github.com/Microsoft/TypeScript/issues/1295#issuecomment -234724380 рдореЗрдВ рд╕реБрдЭрд╛рдпрд╛ рд╣реИред рдпрджреНрдпрдкрд┐ рдпрд╣ рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдпрд╣ рдЗрд╕ рдПрдХ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдм # 11929 рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@weswigham @mhegazy , рдФрд░ рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ; рд╣рдо рдЖрдкрдХреЛ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдП рдЬрд╛ рд░рд╣реЗ рдХрд┐рд╕реА рднреА рдШрдЯрдирд╛рдХреНрд░рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВрдЧреЗ, рдФрд░ рдпрд╣ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рд╡рд┐рдЪрд╛рд░ рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╣реИред
рд╡рд░реНрддрдорд╛рди рд╡рд┐рдЪрд╛рд░:
keysof Foo
рдСрдкрд░реЗрдЯрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВFoo
рд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдореЛрдВ рдХреА рдпреВрдирд┐рдпрди рдХреЛ рд╣рдерд┐рдпрд╛рдиреЗ рдХреЗ рд▓рд┐рдПредFoo[K]
рдкреНрд░рдХрд╛рд░ рдЬреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдкреНрд░рдХрд╛рд░K
рд▓рд┐рдП рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдорд┐рд▓рди рд╣реИредрдЗрди рдмреБрдирд┐рдпрд╛рджреА рдмреНрд▓реЙрдХреЛрдВ рд╕реЗ, рдпрджрд┐ рдЖрдкрдХреЛ рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ
рдпрд╣рд╛рдВ,
K
keysof T
рдХрд╛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдШ рд╣реИред рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛key
рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрд╕реЗ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдЙрд╕ рд╢рд╛рдмреНрджрд┐рдХ / рд╢рд╛рдмреНрджрд┐рдХ рд╕рдВрдШ рджреНрд╡рд╛рд░рд╛ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПредрдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
рд╕рдмрд╕реЗ рдмрдбрд╝рд╛ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐
keysof
рдЕрдХреНрд╕рд░ рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ "рджреЗрд░реА" рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдмрд╣реБрдд рдЙрддреНрд╕реБрдХ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдореИрдВрдиреЗ рдЬреЛ рдкрд╣рд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдерд╛ (рдпрд╛рдиреА рдЬрд┐рд╕ рдорд╛рдорд▓реЗ рдХреЛ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрдард┐рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ: рдореБрд╕реНрдХрд╛рди :)редрдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕рднреА рдХреЛ рдПрдХ рдЕрджреНрдпрддрди рджреЗрддрд╛ рд╣реИред